版权声明:本文为博主原创文章,未经博主允许不得转载。

前一阵写项目,终于将这个boost下的xml读取类完成了,由于网上对property_trees的讲解很少,最多也就到get_child这个层面,所以我写起来很困难,前前后后用了两个星期左右吧,后来发现property_trees要是用好了操作特别骚,而且思路还挺简单的。

目前网上基本上都是在教你读这样的xml

<root>
<delfile>
<filenum> 35 </filenum>
<paths>
<path>
<pathname>/tmp/tmp0/</pathname>
<before_hours> 0 </before_hours>
</path>
</delfile>
<backup>
<backuptime> 23:59 </backuptime>
</backup>
</root>

这样的xml很low,没有任何的信息。一般的xml都是这样的

<?xml version="1.0" encoding="utf-8"?>
<root>
<Item name="project" desc="">
<ChildItem name="project1" desc="file size" datatype="int">600</ChildItem>
<ChildItem name="project2" desc="file size" datatype="int">353</ChildItem>
<ChildItem name="project3" desc="file size" datatype="int">756</ChildItem>
<ChildItem name="project4" desc="file size" datatype="int">888</ChildItem>
</Item>
</Config>

像这样的xml才有价值,但是这里所有的child都一样,并且包含很多的属性,我们怎么去读取value呢?

0X01 遍历方法一

通过遍历读取到map里,再从map中赛选数据

ptree m_pt;
string strAttrName;
BOOST_FOREACH(ptree::value_type &v1, m_pt.get_child(L"root"))
{
if (v1.first == L"Item")
{
strAttrName=v1.second.get<string>(L"<xmlattr>.name");
}

}

这样我们就通过FOREACH遍历出来第一层xml的属性的值“project”,属性是('<xmlattr>')注释是('<xmlcomment>')
那么想在遍历出第二层的属性同样在里面再来一层FOREACH,但是这一层FOREACH要继承上面第一层的value_type的值

BOOST_FOREACH(wptree::value_type &v2, v1.second)
{
if (v2.first == L"ChildItem")
{
string strChildAttrName = v2.second.get<wstring>(L"<xmlattr>.name");
              //取属性
}
}

取值直接用date()就行,value_type有两个方法,第一个方法是first()取得是节点名例如“Item ”,而第二个方法date()取的是节点的属性或者是value。

string value = v2.second.data();

最后将两个循环出来的值分别插入两个map里

ptree m_pt;
string strAttrName;
BOOST_FOREACH(ptree::value_type &v1, m_pt.get_child(L"root"))
{
if (v1.first == L"Item")
{
strAttrName=v1.second.get<string>(L"<xmlattr>.name");
}
       BOOST_FOREACH(wptree::value_type &v2, v1.second)
{
if (v2.first == L"ChildItem")
{
string strChildAttrName = v2.second.get<wstring>(L"<xmlattr>.name");//取属性
string value = v2.second.data();
map1.insert(pair<string, string>(strChildAttrName, value )
}
}
m_map2.insert(pair < string, map<string, string>>(strAttrName, map1));
}

最后map2就是你得到的xml树,当然你也可以多获得一些属性放进去,并做一些处理。

0X02 遍历方法二

如果嫌FOREACH效率太低,你也可以用for循环来遍历xml树

首先我们要是用到for循环的话,必须用到ptree中的find()方法,但是find()方法没法深入查找,什么叫无法深入查找?就是说你套了两层xml(就像我的例子一样)他就无法查找了,所以我们必须先将最外一层节点去掉

ptree pt;
pt = pt.get_child(L"root");

将节点指向自己,这样就可以去掉最外一层节点。以后需要遍历查找

for (wptree::assoc_iterator iter = pt.find(L"Item"); iter != pt.not_found() && !bfind; ++iter)
{
auto strAttrName = iter->second.get<wstring>(L"<xmlattr>.name");
}

这样可以遍历出在外层的节点的属性

第二层节点通过第一层节点的迭代器来来迭代

for (wptree::assoc_iterator iter2 = iter->second.find(L"ChildItem"); iter2 != iter->second.not_found(); ++iter2)
{
auto strChildAttrName = iter2->second.get<wstring>(L"<xmlattr>.name");
}

具体实现

for (wptree::assoc_iterator iter = pt.find(L"Item"); iter != pt.not_found() && !bfind; ++iter)
{
auto strAttrName = iter->second.get<string>(L"<xmlattr>.name");
    for (wptree::assoc_iterator iter2 = iter->second.find(L"ChildItem"); iter2 != iter->second.not_found(); ++iter2)
{
  auto strChildAttrName = iter2->second.get<string>(L"<xmlattr>.name");         
    }
}

之后分别输出、修改值、或者存入xml中都可以,但是因为最外层的节点已经删除了,所以我们还得吧最外层的节点找回来

ptree pt1;
pt = pt.get_child(L"Config");
........
.......
pt1.add_child(L"Config", pt);
m_pt.clear();
m_pt = pt1;

必须再建一个ptree,这样加节点的时候才不会乱。

0X03 增加节点

增加就特别好说了

vector<string> vect_str;
vector<string>::iterator it; vect_str.push_back("");
vect_str.push_back("");
vect_str.push_back("");
vect_str.push_back(""); for (it = vect_str.begin(); it != vect_str.end(); it++) { //迭代vector
data.put("<xmlattr>.key",it->data());
info.add_child("data",data);
data.clear() ;
}
pt.add_child("root.output.info",info)

放入map或者vactor里都行,之后遍历增加

0X04 删除节点

删除也一样,遍历之后删除节点。

ptree& persons = pt.get_child("root.persons");
for(auto it = persons.begin(); it != persons.end();)
{
if(it->second.get<string>("name") == "dad")
it = persons.erase(it);
else
++it;
}

0X05 修改值

改也很简单,遍历出所要改的值在节点,直接赋值然后再写回去就行了。

iter2->second.put_value(value);

0X06 抛出异常

增删改查都说完了,再说说异常吧,property_tree的异常分两种,一种是路径错误,一种是值错误很好判断,异常直接告诉你哪个属性等有问题

try
{
.......
}
catch (boost::property_tree::ptree_bad_path& e)
{
m_error = e.what();
return false;
}
catch (boost::property_tree::ptree_bad_data& e)
{
m_error =e.what();
return false;
}

研究了一个月,我敢说property_tree这个类库我用的国内最熟233333

boost.property_tree的高级用法(你们没见过的操作)的更多相关文章

  1. Requests库的文档高级用法

    高级用法 本篇文档涵盖了 Requests 的一些高级特性. 会话对象 会话对象让你能够跨请求保持某些参数.它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 url ...

  2. Go template高级用法、深入详解、手册、指南、剖析

    入门示例 以下为test.html文件的内容,里面使用了一个template语法{{.}}. <!DOCTYPE html> <html> <head> <m ...

  3. python requests 高级用法

    高级用法 本篇文档涵盖了 Requests 的一些高级特性. 会话对象 会话对象让你能够跨请求保持某些参数.它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 url ...

  4. Python面试常用的高级用法,怎么动态创建类?

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第16篇文章,今天我们来聊聊Python当中的元类. 元类是Python当中的高级用法,如果你之前从来没见过这个术语 ...

  5. Bash 脚本编程的一些高级用法

    概述 偶然间发现 man bash 上其实详细讲解了 shell 编程的语法,包括一些很少用却很实用的高级语法.就像发现了宝藏的孩子,兴奋莫名.于是参考man bash,结合自己的理解,整理出了这篇文 ...

  6. Visual Studio 宏的高级用法

    因为自 Visual Studio 2012 开始,微软已经取消了对宏的支持,所以本篇文章所述内容只适用于 Visual Studio 2010 或更早期版本的 VS. 在上一篇中,我已经介绍了如何编 ...

  7. Android(java)学习笔记264:Android下的属性动画高级用法(Property Animation)

    1. 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画 ...

  8. nmap命令-----高级用法

    探测主机存活常用方式 (1)-sP :进行ping扫描 打印出对ping扫描做出响应的主机,不做进一步测试(如端口扫描或者操作系统探测):  下面去扫描10.0.3.0/24这个网段的的主机 nmap ...

  9. 细说 ASP.NET Cache 及其高级用法

    许多做过程序性能优化的人,或者关注过程程序性能的人,应该都使用过各类缓存技术. 而我今天所说的Cache是专指ASP.NET的Cache,我们可以使用HttpRuntime.Cache访问到的那个Ca ...

随机推荐

  1. hdu5391Zball in Tina Town

    //求(n-1)!%n //n 为合数,答案为0,n为素数 . 威尔逊定理可得 //判定一个自然数是否为素数的充分必要条件. 即:当且仅当p为素数时:( p -1 )! ≡ -1 ( mod p ) ...

  2. QTP11.5公布,改名UFT

    QTP11.5公布,改名UFT,支持多脚本编辑调试.PDF检查点.持续集成系统.手机測试等 http://www.learnqtp.com/hp-uft11-5-qtp-new-features/ T ...

  3. angularjs 自定义服务

    <!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...

  4. poj--3620--Avoid The Lakes(dfs)

    Avoid The Lakes Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Subm ...

  5. TabLayout禁止选择

    项目中有个页面上面是TabLayout下面是Listview,选择TabLayout的选项卡更新下面Listview里面的数据,在请求的时候想禁用TabLayout选项卡来避免用户频繁点击选项卡造成L ...

  6. PostgreSQL Replication之第四章 设置异步复制(7)

    4.7 冲突管理 在PostgreSQL中,流复制数据仅在一个方向流动.XLOG由master提供给几个slave,这些slave消耗事务日志并为您提供一个较好的数据备份.您可能想知道这怎么会导致冲突 ...

  7. 使用python抓取App数据

    App接口爬取数据过程使用抓包工具手机使用代理,app所有请求通过抓包工具获得接口,分析接口反编译apk获取key突破反爬限制需要的工具:夜神模拟器FiddlerPycharm实现过程首先下载夜神模拟 ...

  8. ReactiveCocoa 中 RACSignal 所有变换操作底层实现分析(上)

    前言 在上篇文章中,详细分析了RACSignal是创建和订阅的详细过程.看到底层源码实现后,就能发现,ReactiveCocoa这个FRP的库,实现响应式(RP)是用Block闭包来实现的,而并不是用 ...

  9. Ubuntu18.04 解压zip文件乱码的解决方法

    在Ubuntu的系统下解压zip文件的时候居然出现了乱码,通过查找网上的资料,解决的办法有两种 一.通过unzip行命令解压,指定字符集,由于zip格式中并没有指定编码格式,Windows下生成的zi ...

  10. bzoj2124 等差子序列(树状数组+hash)

    题意 给你一个1~n排列,问有没有一个等差数列(长度至少为3) 题解 我居然自己想到了正解. 但我最后写挂了,所以我又看了题解. 我们维护了一个以权值为下标的01序列. 我们扫描整个序列.对于每一个正 ...