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 ...
随机推荐
- 6.5.2 C# 中的函数组合
6.5.2 C# 中的函数组合 C# 中的函数组合是可能的.但使用非常有限,这是部分是由于在 C# 中散应用不能非常easy使用.但更重要的是,由于大多数操作是用成员来写的.而不是函数.但我们至少能够 ...
- [NOI2002] Robot 解题报告(数论+DP)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1408 Description 3030年,Macsy正在火星部署一批机器人. 第1秒,他 ...
- Chrome Foundation Services
Chrome Foundation Services Contents Overview API Standards Service Directory Structure Dependencies ...
- d3的一些总结
核心操作:https://blog.csdn.net/kriszhang/article/details/70174410 Update.Enter.Exit 简练详细说明:http://www.cn ...
- dist文件夹、src文件夹、dest文件夹是什么意思?
dist文件夹是编译后或者压缩后的代码,终发布版本的代码 src文件夹是源码文件 dest文件夹为压缩包文件夹
- cmder-替代cmd
之所以选择cmder,说来话长,在学习python的过程中,由于经常通过pip命令安装包,并且在学习一些包的使用例如virtualenv,教程贴都是在终端下的命令,这使我对cmd的使用频率慢慢变多了起 ...
- COGS——T 8. 备用交换机
http://www.cogs.pro/cogs/problem/problem.php?pid=8 ★★ 输入文件:gd.in 输出文件:gd.out 简单对比时间限制:1 s 内存 ...
- 荣耀A55高调上市仅仅为孤独求败?
坦白说.华为近年来在手机市场上确实取得了一些成绩.比方之前P6的出现就凭借超薄的设计.突出的性价比让大家看到了国产手机的新希望.按理说.在手机市场上尝到甜头的华为应该继续坚持低价.亲民的路线, ...
- IDEA中的maven web 项目中如何设置自己的本地仓库
我们在创建maven项目的时候如何不使用系统指定的本地仓库,而使用自己设置的仓库呢,这里小女子就来进行讲解一下吧! 讲解一:你要想找到settings.xml你就要自己我去官网上去下载apache-m ...
- Activity的launchMode和任务栈小结
对Activity的launchMode的理解一直没有好好总结下,这两天系统总结下launchMode的使用方法: Activity的launchMode属性决定了Activity和应用程序当前任务栈 ...