Boost property_tree 解析配置文件

在日常的开发系统中,不可避免的会解析配置文件,因为使用配置文件更直观,而且修改配置文件就不用再编译代码,当工程很大的时候,编译代码会是一件很痛苦的事。不同的需求的配置文件不同,Boost提供了一个property_tree来解析.xml,.ini,.json,.info四种格式配置文件。

.xml文件

.xml现在已经被广泛应用到数据交换格式,并且property_tree是树形结构,和.xml文件格式很相近。基本格式是<attribute> value </attribute> ,属性包含属性值的形式。现在以学生信息举例。

<conf>
<school> scu </school>
<person>
    <name> freehyan </name>
    <sex> male </sex>
    <age> 22 </age>
</person>
</conf>

property_tree 源码浅析

template <typename Key, typename Data, typename KeyCompare>
class basic_ptree
{
    public:
        typedef basic_ptree<Key, Data, KeyCompare> self_type;
        typedef std::pair<const Key, self_type>    value_type;

        basic_ptree();
        basic_ptree& operator=(const self_type & );

    //...

        data_type& data();
        template<typename Type> Type get(const path_type &) const;

        self_type& get_child(const path_type &);
        self_type& put_child(const path_type &, const self_type &);
        self_type& add_child(const path_type &, const self_type &);
    //...
}

property_tree的核心类是basic_tree,内部重新定义了两个重要类型self_type, value_type。self_type是模板实例化的自身类型,而value_type是节点的数据结构,本质是std::pair,含有节点的属性名和本身。最后几个函数是获取,添加等操作,注意源码内容不止于此。basic_tree不能直接使用,通常使用的是 typedef basic_ptree<std::string, std::string> ptree;

读取.xml

Boost中property_tree内部使用的是小巧开源xml解析器–rapidxml。读取配置文件是通过read_xml函数,当节点不存在的时候,会抛出异常。

  • 在初始化ptree后,可以使用get()通过路径访问属性树内节点,用模板参数指明获取属性的类型。路径分隔符是(.),小数点的样子。
    如: pt.get<std::string>("conf.theme")
  • ptree的get()函数支持缺省值的用法,即如果属性不存在,则使用缺省值。由于缺省值已经有类型信息,因此get()的返回值类型可以自动推导,所以不必再加模板参数。
    如:pt.get("conf.theme", 100);
  • 访问有多个属性值的子节点,比如第一部分中的person就是这样的子节点。可以通过迭代器的方式访问获取值。
auto child =  pt.get_child("conf.person");
for (auto& x  : child)
{
    std::cout << x.first;
    std::cout << x.second.get_value<std::string>() << std::endl;
}
for (auto pos=child.begin(); pos != child.end(); pos++)
{
    std::cout << pos->second.get_value<std::string>() << std::endl;
}

写入.xml

有读就有写,property_tree也支持写入配置信息,从源码中就可以看出相应的函数,使用模板函数put()可以修改属性树的节点值,如果节点不存在就新增节点,如果存在就修改属性值。不过通常put()不需要指定模板参数,因为和缺省值读取一样,写入也可以自行推导。

    pt.put("conf.theme", "black theme");
    boost::property_tree::write_xml("abc.xml", pt);

更多用法

其实basic_tree的语法很像stl容器,所以大部分的函数api对其也适用,因为它就像std::list<std::string, boost::property_tree::ptree> ,比如可以使用find函数。
属性树的标签名是属性名,内容是属性值。节点的属性保存在节点<xmlattr>的下级节点,注释保存在<xmlcomment>中。

<conf>
<!-- comment -->
<theme id = "1001"> black theme </theme>
</conf>
boost::property_tree::ptree pt;
boost::property_tree::read_xml("abc.xml", pt);
std::cout << pt.get<std::string>("conf.<xmlcomment>") << std::endl;
std::cout << pt.get<int>("conf.theme.<xmlattr>.id") << std::endl;

参考

【1】 Boost 程序库完全开发指南,书籍
【2】http://www.cnblogs.com/qicosmos/p/3555668.html
【3】http://www.boost.org/doc/libs/1_60_0/doc/html/property_tree.html

你可能感兴趣的:(Boost property_tree 解析配置文件)