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

前一阵写项目,终于将这个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. 【我所认知的BIOS】系列blog整理 1.23.2016.zip

    这几年来,蛮多小伙伴都给我发邮件拿PDF版本号. 几年前写的文章格式什么的实在是太粗糙.近期我把全部的文章都整理了一下.事实上该想法已经早就有了,仅仅是近期才開始空暇.如今我把全部的文章整理好了以后上 ...

  2. input range 模拟滑块

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  3. HDU1232 畅通project 并查集

    这道题跟HDU 1213 How Many Tables 并查集很接近,都是赤裸裸的并查集的题. 思路:如果还须要建n-1条路.每并一次就自减1. 參考代码: #include<stdio.h& ...

  4. [poj 3904] sky code 解题报告(组合计算+容斥原理)

    题目链接:http://poj.org/problem?id=3904 题目大意: 给出一个数列,询问从中取4个元素满足最大公约数为1的方案数 题解: 很显然,ans=总的方案数-最大公约数大于1的4 ...

  5. POJ 3173 模拟

    按照题意模拟就好-- //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; in ...

  6. Kali linux 2016.2(Rolling)里Metasploit的常用模块

    端口扫描 auxiliary/scanner/portscanscanner/portscan/ack ACK防火墙扫描scanner/portscan/ftpbounce FTP跳端口扫描scann ...

  7. 使用ajax验证用户名重复

    继上次的用户注册登录案例之后,对其中的部分功能再做进一步改进.上一版中用户提交表单后才对用户名进行校验,虽然做了回显,但还是感觉功能弱了些.为了能有更好用户体验,不是在用户提交表单后才给提示,而是在用 ...

  8. CSS动画框架Loaders.css +animate.css

    CSS加载动画框架Loaders.css 是一款非常出色的加载动画框架,Loaders.css利用纯CSS可以实现很多种样式的Loading加载动画,这些动画并不需要图片来辅助,而是仅仅需要CSS即可 ...

  9. python web开发 框架 模板 MVC

    我是跟着廖雪峰老师学习的,对于我这样的纯小白来说,跟着他的网站学习,简直是被妈妈抱在怀里一样无忧无虑,这样的学习本来没有记录下来的必要,但是由于我的粗心大意,经常会出现一些错误,所以我决定把这些错误记 ...

  10. 今日SGU 5.29

    sgu 299 题意:给你n个线段,然后问你能不能选出其中三个组成一个三角形,数字很大 收获:另一个大整数模板 那么考虑下为什么如果连续三个不可以的话,一定是不存在呢? 连续上个不合法的话,一定是 a ...