property_tree

  • property_tree是一个保存了多个属性值的树形数据结构,可以用来解析xml、json、ini、info文件。

  • 要使用property_tree和xml解析组件的话需要包含"boost/property_tree/ptree.hpp"和"boost/property_tree/xml_parser.hpp"。

  • 我们一般使用property_tree中预定义好的typedef: ptree来处理数据。

xml

格式

<?xml version="1.0" encoding="UTF-8"?>
<conf>
    <gui>0</gui>
    <theme>matrix</theme>
    <urls>
        <url>http:://www.url1.com</url>
        <url>http:://www.url2.com</url>
        <url>http:://www.url3.com</url>
        <url></url>
    </urls>
    <clock_style>24.35</clock_style>
</conf>

解析

#include <cstdio>
#include <string>
#include <iostream>
using std::string;
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/xml_parser.hpp"
#include "boost/typeof/typeof.hpp"
#include "boost/optional.hpp"
using namespace boost::property_tree;

int main()
{
    ptree pt;
    read_xml("conf.xml", pt);

    boost::optional<int> op = pt.get_optional<int>("conf.gui");
    //使用get_optional()获得节点,不存在则op为空
    if (op)
    {
        int i = op.get();
    }

    string str1 = pt.get<string>("conf.theme", "");
    //使用get()获得节点,不存在则返回""

    boost::optional<ptree&> child_null_test = pt.get_child_optional("conf.urls");
    if (child_null_test)
    {
        BOOST_AUTO(child, pt.get_child("conf.urls"));
        for (BOOST_AUTO(pos, child.begin()); pos != child.end(); ++pos)
        {
            string str = pos->second.get_value<string>();
            std::cout << str << std::endl;
        }
    }

    string str = pt.get("conf.clock_style", "");
}

添加

    ptree pt;
    read_xml("conf.xml", pt);
    pt.add("conf.urls.url", "http://www.url4.com");
    write_xml("conf.xml", pt);

修改

	ptree pt;
    read_xml("conf.xml", pt);
    pt.put("conf.gui", 99);
    write_xml("conf.xml", pt);

节点属性

格式

<?xml version="1.0" encoding="UTF-8"?>
<conf><!--conf comment-->
    <gui>1</gui>
    <theme id="001">matrix</theme>
    <urls><!--urls comment-->
    </urls>
</conf>

解析

	ptree pt;
    read_xml("conf.xml", pt);
    boost::optional<string> op = pt.get_optional<string>("conf.<xmlcomment>");
    if (op)
    {
        string strCommentConf = op.get();
    }
    op = pt.get_optional<string>("conf.urls.<xmlcomment>");
    if (op)
    {
        string strCommentUrls = op.get();
    }
    op = pt.get_optional<string>("conf.theme.<xmlattr>.id");
    if (op)
    {
        string strAttr = op.get();
    }

json

  • 使用property_tree解析json与解析xml的接口方法基本相同,不同的地方是读取json文件使用read_json,写入json文件使用write_json

格式


{
    "conf":
    {
        "gui": 1,
        "theme": "matrix",
        "urls":
        {
            "url": "http://www.url1.com",
            "url": "http://www.url2.com",
            "url": "http://www.url3.com"
        },
        "clock_style": 24
    }
}

解析

#include <cstdio>
#include <string>
#include <iostream>
using std::string;
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/json_parser.hpp"
#include "boost/typeof/typeof.hpp"
#include "boost/optional.hpp"
using namespace boost::property_tree;

int main()
{
    ptree pt;
    read_json("conf.json", pt);

    boost::optional<int> op = pt.get_optional<int>("conf.gui");
    //不存在则op为空
    if (op)
    {
        int i = op.get();
        int a = 0;
    }

    string str1 = pt.get<string>("conf.theme", "");

    boost::optional<ptree&> child_null_test = pt.get_child_optional("conf.urls");
    if (child_null_test)
    {
        BOOST_AUTO(child, pt.get_child("conf.urls"));
        for (BOOST_AUTO(pos, child.begin()); pos != child.end(); ++pos)
        {
            string str = pos->second.get_value<string>();
            std::cout << str << std::endl;
        }
    }

    string str = pt.get("conf.clock_style", "");
    
    return getchar();
}