Boost.PropertyTree 五分钟快速入门
本教程使用XML。注意,这个库不是专门绑定到XML的,而是可以使用任何其他支持的格式(如INI或JSON)。之所以选择XML,是因为作者认为很多人都熟悉XML。
假设我们正在为某个应用程序编写一个日志系统,并且需要在程序启动时从文件中读取日志配置。带有日志配置的文件如下所示:
<debug><filename>debug.log</filename><modules><module>Finance</module><module>Admin</module><module>HR</module></modules><level>2</level></debug>
它包含日志文件名、启用日志记录的模块列表和调试级别值。
我们需要包含的头文件:
#include<boost/property_tree/ptree.hpp>#include<boost/property_tree/xml_parser.hpp>#include<boost/foreach.hpp>#include<string>#include<set>#include<exception>#include<iostream>namespace pt = boost::property_tree;
为了存储日志的配置信息,我们创建一个结构来存储它
struct debug_settings{std::string m_file;// log filenameint m_level;// debug levelstd::set<std::string> m_modules;// modules where logging is enabledvoid load(const std::string &filename);void save(const std::string &filename);};
现在需要做的就是编写load()和save()成员函数的实现。让我们先来处理load()。它只包含7行代码,尽管它做了所有必要的事情,包括错误报告:
void debug_settings::load(const std::string &filename){// Create empty property tree objectpt::ptree tree;// Parse the XML into the property tree.pt::read_xml(filename, tree);// Use the throwing version of get to find the debug filename.// If the path cannot be resolved, an exception is thrown.m_file = tree.get<std::string>("debug.filename");// Use the default-value version of get to find the debug level.// Note that the default value is used to deduce the target type.m_level = tree.get("debug.level",0);// Use get_child to find the node containing the modules, and iterate over// its children. If the path cannot be resolved, get_child throws.// A C++11 for-range loop would also work.BOOST_FOREACH(pt::ptree::value_type &v, tree.get_child("debug.modules")){// The data function is used to access the data stored in a node.m_modules.insert(v.second.data());}}
存储函数
void debug_settings::save(const std::string &filename){// Create an empty property tree object.pt::ptree tree;// Put the simple values into the tree. The integer is automatically// converted to a string. Note that the "debug" node is automatically// created if it doesn't exist.tree.put("debug.filename", m_file);tree.put("debug.level", m_level);// Add all the modules. Unlike put, which overwrites existing nodes, add// adds a new node at the lowest level, so the "modules" node will have// multiple "module" children.BOOST_FOREACH(const std::string &name, m_modules)tree.add("debug.modules.module", name);// Write property tree to XML filept::write_xml(filename, tree);}
来个全代码的:
//// Created by 瓜不甜 on 2018/1/20.//#include<boost/property_tree/ptree.hpp>#include<boost/property_tree/xml_parser.hpp>#include<boost/foreach.hpp>#include<string>#include<set>#include<exception>#include<iostream>namespace pt = boost::property_tree;struct debug_settings{std::string m_file;// log filenameint m_level;// debug levelstd::set<std::string> m_modules;// modules where logging is enabledvoid load(const std::string &filename);void save(const std::string &filename);};void debug_settings::load(const std::string &filename){// Create empty property tree objectpt::ptree tree;// Parse the XML into the property tree.pt::read_xml(filename, tree);// Use the throwing version of get to find the debug filename.// If the path cannot be resolved, an exception is thrown.m_file = tree.get<std::string>("debug.filename");// Use the default-value version of get to find the debug level.// Note that the default value is used to deduce the target type.m_level = tree.get("debug.level",0);// Use get_child to find the node containing the modules, and iterate over// its children. If the path cannot be resolved, get_child throws.// A C++11 for-range loop would also work.BOOST_FOREACH(pt::ptree::value_type &v, tree.get_child("debug.modules")){// The data function is used to access the data stored in a node.m_modules.insert(v.second.data());}}void debug_settings::save(const std::string &filename){// Create an empty property tree object.pt::ptree tree;// Put the simple values into the tree. The integer is automatically// converted to a string. Note that the "debug" node is automatically// created if it doesn't exist.tree.put("debug.filename", m_file);tree.put("debug.level", m_level);// Add all the modules. Unlike put, which overwrites existing nodes, add// adds a new node at the lowest level, so the "modules" node will have// multiple "module" children.BOOST_FOREACH(const std::string &name, m_modules)tree.add("debug.modules.module", name);// Write property tree to XML filept::write_xml(filename, tree);}void test1(){debug_settings a;a.load("setting.xml");std::cout<<a.m_file<<std::endl;std::cout<<a.m_level<<std::endl;std::set<std::string>::iterator i;for( i = a.m_modules.begin(); i != a.m_modules.end();++i){std::cout<<*i<<std::endl;}}

很明显,这个是个非常好用的结构!
简单,高效!
这里有个foreach结构:
BOOST_FOREACH(const std::string &name, m_modules)
{
tree.add("debug.modules.module", name);
}
这个是C++的一个类宏的高级应用了

浙公网安备 33010602011771号