使用boost property_tree 生成XML配置文件

         boost.property_tree可以用来解析xml和json文件,我主要用它来解析xml文件,它内部封装了号称最快的xml解析器rapid_xml,其解析效率还是很好的。但是在使用过程中却发现各种不好用,归纳一下不好用的地方有这些:

获取不存在的节点时就抛出异常 获取属性值时,要排除属性和注释节点,如果没注意这一点就会抛出异常,让人摸不着头脑。 内存模型有点怪。 默认不支持中文的解析。解析中文会乱码。
ptree获取子节点

  获取子节点接口原型为get_child(node_path),这个node_path从当前路径开始的全路径,父路径和子路径之间通过“.”连接,如“root.sub.child”。需要注意的是get_child获取的是第一个子节点,如果我们要获取子节点列表,则要用路径“root.sub”,这个路径可以获取child的列表。如果获取节点的路径不存在则会抛出异常,这时,如果不希望抛出异常则可以用get_xxx_optional接口,该接口返回一个optional<T>的结果出来,由外面判断是否获取到结果了。

//ptree的optional接口
auto item = root.get_child_optional('Root.Scenes');

ptree的内存模型

  ptree维护了一个pair<string, ptree>的子节点列表,first指向的是该节点的TagName,second指向的才是ptree节点,因此在遍历ptree子节点时要注意迭代器的含义。

for(auto& data ; root){
    for( auto& item : data.second ) //列元素为pair<string, ptree>,要用second继续遍历
        {
              cout<<item.first<<endl;
        }
}
           需要注意的是ptree.first可能是属性('<xmlattr>')也可能是注释('<xmlcomment>'),只有非注释类型的节点才能使用获取属性值、子节点等常用接口。
ptree获取属性值

  通过get<T>(attr_name)可以获取属性的值,如果想获取属性的整形值的话,可以用get<int>('Id'),返回一个整数值。有一点要注意如果ptree.first为'<xmlcomment>'时,是没有属性值的,可以通过data()来获取注释内容。如果这个ptree.first不为<xmlattr>时需要在属性名称前面加'<xmlcomment>.',即get<int>('<xmlcomment>.Id')才能正确获取属性值。可以看到获取属性值还是比较繁琐的,在后面要介绍的帮助类中可以简化属性值的获取。如果要获取节点的值则用get_value()接口,该接口用来获取节点的值,如节点:<Field>2</Field>通过get_value()就可以获取值'2'。

以上为转载,原文链接地址:http://www.it165.net/pro/html/201402/9374.html    原文中提供了解决 解析XML中中文字符的方法!


下面来了解一下property_tree的两个函数put() 和add_child()的用法。

ptree  pt ; //定义一个树,
pt.put(const path_type& path, const type& value) ;
功能:把value设置成节点的值,并把节点转换成树的数据类型。
参数:
    path:该节点的路径
    value:该节点的值
返回值:成功返回  值已被改变的节点
              如果转化失败,抛出 ptree_bad_data;
 
pt.add_child(const path_type& path, const self_type& value);
功能:向树pt中添加节点(子树)value
参数:
    path:添加节点的路径
    value:节点(子树)
返回值:插入的子树的引用

使用形式:
rule.put("<xmlattr>.version" ,"123");
pt.add_child("root.soinfo",rule);
输出为:在给定的路径添加节点
<root>
    <soinfo desc = "123"/>
</root>

rule.put("soinfo.<xmlattr>.version" ,"123");
pt.add_child("root",rule);
输出为:
<root>
    <soinfo>
        <soinfo desc = "123"/>
    </soinfo>
</root>


下面是测试代码   main.cpp

#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <vector>

using namespace std;

int main(int argc, char** argv) {
    vector<string> vect_str;
    vector<string>::iterator it;

    vect_str.push_back("111111");
    vect_str.push_back("222222");
    vect_str.push_back("333333");
    vect_str.push_back("444444");

    using namespace boost::property_tree;
    ptree pt;   //定义一个树pt
    ptree out;
    ptree cond;
    ptree rule;
    ptree data ;
    ptree info ;
    
    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);
    info.clear();
        
    BOOST_FOREACH(std::string& str, vect_str) { //迭代vector
        for (int i = 0; i < 2; i++) {
            cond.put("<xmlattr>.desc", "123");
            cond.put("<xmlattr>.path", "345");
            cond.put("<xmlattr>.version", "567");
            cond.put("<xmlattr>.priority", "789");
            rule.add_child("cond", cond);
            cond.clear();
        }
        out.put("<xmlattr>.where", str);
        rule.add_child("out",out);
        out.clear();
        pt.add_child("root.output.rule", rule);
        rule.clear();
    }
	//设置写入xml文件的格式,
    boost::property_tree::xml_writer_settings<char> settings('\t', 1); 
	//把property_tree 转为XML文件
    write_xml("newconfig.xml", pt, std::locale(), settings);
	
    return 0;
}

下面是生成的XML文件 newconfig.xml 

<?xml version="1.0" encoding="utf-8"?>
<root>
	<output>
		<info>
			<data key="111111"/>
			<data key="222222"/>
			<data key="333333"/>
			<data key="444444"/>
		</info>
		<rule>
			<cond desc="123" path="345" version="567" priority="789"/>
			<cond desc="123" path="345" version="567" priority="789"/>
			<out where="111111"/>
		</rule>
		<rule>
			<cond desc="123" path="345" version="567" priority="789"/>
			<cond desc="123" path="345" version="567" priority="789"/>
			<out where="222222"/>
		</rule>
		<rule>
			<cond desc="123" path="345" version="567" priority="789"/>
			<cond desc="123" path="345" version="567" priority="789"/>
			<out where="333333"/>
		</rule>
		<rule>
			<cond desc="123" path="345" version="567" priority="789"/>
			<cond desc="123" path="345" version="567" priority="789"/>
			<out where="444444"/>
		</rule>
	</output>
</root>









  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值