boost.property_tree的高级用法(你们没见过的操作)
版权声明:本文为博主原创文章,未经博主允许不得转载。
前一阵写项目,终于将这个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的高级用法(你们没见过的操作)的更多相关文章
- Requests库的文档高级用法
高级用法 本篇文档涵盖了 Requests 的一些高级特性. 会话对象 会话对象让你能够跨请求保持某些参数.它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 url ...
- Go template高级用法、深入详解、手册、指南、剖析
入门示例 以下为test.html文件的内容,里面使用了一个template语法{{.}}. <!DOCTYPE html> <html> <head> <m ...
- python requests 高级用法
高级用法 本篇文档涵盖了 Requests 的一些高级特性. 会话对象 会话对象让你能够跨请求保持某些参数.它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 url ...
- Python面试常用的高级用法,怎么动态创建类?
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第16篇文章,今天我们来聊聊Python当中的元类. 元类是Python当中的高级用法,如果你之前从来没见过这个术语 ...
- Bash 脚本编程的一些高级用法
概述 偶然间发现 man bash 上其实详细讲解了 shell 编程的语法,包括一些很少用却很实用的高级语法.就像发现了宝藏的孩子,兴奋莫名.于是参考man bash,结合自己的理解,整理出了这篇文 ...
- Visual Studio 宏的高级用法
因为自 Visual Studio 2012 开始,微软已经取消了对宏的支持,所以本篇文章所述内容只适用于 Visual Studio 2010 或更早期版本的 VS. 在上一篇中,我已经介绍了如何编 ...
- Android(java)学习笔记264:Android下的属性动画高级用法(Property Animation)
1. 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画 ...
- nmap命令-----高级用法
探测主机存活常用方式 (1)-sP :进行ping扫描 打印出对ping扫描做出响应的主机,不做进一步测试(如端口扫描或者操作系统探测): 下面去扫描10.0.3.0/24这个网段的的主机 nmap ...
- 细说 ASP.NET Cache 及其高级用法
许多做过程序性能优化的人,或者关注过程程序性能的人,应该都使用过各类缓存技术. 而我今天所说的Cache是专指ASP.NET的Cache,我们可以使用HttpRuntime.Cache访问到的那个Ca ...
随机推荐
- 安卓开发--HttpDemo02
package com.cnn.httpdemo02; import android.app.Activity; import android.os.Bundle; import android.vi ...
- POJ 3204 网络流的必须边
思路: 求一遍网络流 在残余网络上DFS 从起点DFS 从终点把边反向DFS 一个边跟起点连通 跟终点反向的边连通 ans++ 注:此题不能用tarjan 因为有边权为0的边 //By SiriusR ...
- coedforces #481Div(3)(ABCDEFG)
A. Remove Duplicates Petya has an array aconsisting of nintegers. He wants to remove duplicate (equa ...
- Web开发、原生开发、混合开发的区别优势:
一.Web 应用 Web应用本质上是为移动浏览器设计的基于Web的应用,它们是用普通Web开发语言开发的,可以在各种智能手机浏览器上运行. 优点: 支持设备广泛: 较低的开发成本: 可即时上线: 无内 ...
- affe(8) solver 优化方法
上文提到,到目前为止,caffe总共提供了六种优化方法: Stochastic Gradient Descent (type: "SGD"), AdaDelta (type: &q ...
- [Codeforces 841C]Leha and Function
题目大意:定义函数F(n,k)为[1,2,3,..n]中k个元素的子集中最小元素的数学期望.现在给你两个长度相等的数列A,B(A中元素严格大于B中元素),现在要你重新排列A,使得$\sum\limit ...
- linux驱动编译时候出现的问题
1.在编译驱动的时候,提示错误,找不到<asm/xxxx.h>这些类的头文件? 答:因为在内核编译的时候,会在内核目录的include中创建一个asm文件再软链接到对应的一些架构.比如我当 ...
- Generational GC (Part one )
目录 什么是分代垃圾回收 对象对的年龄 新生代对象和老年对象 Ungar的分带垃圾回收 堆的结构 记录集 写入屏障 对象的结构 分配 新生代GC 幸存空间沾满了怎么办? 老年代GC 优缺点 吞吐量得到 ...
- 20180929 北京大学 人工智能实践:Tensorflow笔记07
(完)
- Unity ContextMenu特性
有时候我们需要在编辑器下,频繁的做一些操作,比如说在不同的位置创建物体,一个个的修改坐标显然有点繁琐 这时候ContextMenu就派上用处了 例:利用 LineRenderer 画圆,我们不可能一个 ...