Boost Property_tree迭代器,如何处理?
-
15-10-2019 - |
题
对不起,我以前询问过一个有关同一主题的问题,但是我的问题涉及那里描述的问题的另一个方面(如何迭代提升...).
查看以下代码:
#include <iostream>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/algorithm/string/trim.hpp>
int main(int argc, char** argv) {
using boost::property_tree::ptree;
ptree pt;
read_xml("try.xml", pt);
ptree::const_iterator end = pt.end();
for (ptree::const_iterator it = pt.begin(); it != end; it++)
std::cout << "Here " << it->? << std::endl;
}
好吧,正如我在我提到的问题中被告知的那样,有可能在 property_tree
在Boost中,但我不知道它是什么类型,以及可以使用哪种方法或属性。
好吧,我认为那一定是另一个 ptree
或代表另一个XML层次结构的内容(如果我愿意的话),但是关于此的文档非常糟糕。我不知道为什么,但是在Boost Docs中,我找不到任何好处,只是关于浏览节点的宏,但是这种方法是我真正想避免的方法。
因此,请在这里解决我的问题:一旦将迭代器放在 ptree
, ,如何访问节点名称,值,参数(XML文件中的节点)?谢谢
解决方案
我同意Andry的观点,并至少发现Property_tree的文档极为最小。我需要PTREE来加载具有不同设置的相同对象,并且难以弄清迭代器迭代的内容,它返回的类型以及它是否会保留在对象级别上,或者通过每个节点BFS般。最后,我设法使我的代码适用于类似于以下情况的情况:
设置文件:
<object1>
<enable>true</enable>
<label>hello</label>
</object1>
<object2>
<enable>false</enable>
<label>goodbye</label>
</object2>
首先,我为我的对象添加了一个构造函数,该构造函数可以在ptree上初始化。请注意,我正在使用默认选项的GET,以防止在失败的GET()::
object::object(const boost::property_tree::ptree &pt_)
{
enable = pt_.get<bool>("enable", true); // usage is: get<type>(path, default)
label = pt_.get<std::string>("label", "empty");
}
最后,以下代码加载两个对象,并将它们放在地图中:
std::map<std::string, my_object> objects_map;
// parse settings file and add loggers
if(filesystem::exists(logger_settings_file))
{
boost::property_tree::ptree pt;
read_xml(logger_settings_file, pt);
BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt)
{
objects_map[v.first] = my_object(v.second);
}
}
因此,回答我自己的问题:
- 迭代器在设置文件上进行迭代,而无需降低较低的级别。运行上述代码您会发现循环迭代两次 - XML文件中每个对象一次。
- 迭代器返回一个类似于一对的value_type对象,并具有
first
和second
登录器。v.first
是一个持有父节点的std ::字符串(在我的情况下,“ object1”,“ object2”),和v.second
是一个boost::property_tree::ptree
, ,可用于解析对象的字段。
其他提示
打印完整的树:
void print(boost::property_tree::ptree const& pt)
{
using boost::property_tree::ptree;
ptree::const_iterator end = pt.end();
for (ptree::const_iterator it = pt.begin(); it != end; ++it) {
std::cout << it->first << ": " << it->second.get_value<std::string>() << std::endl;
print(it->second);
}
}
您应该在输入属性文件上具有先验知识。
Boost Property树不是一般文档解析器。它将进行解析并访问数据,但必须手动找到它。
我不知道有可以导航整个文档的方法,但是如果您只需要自己的文件的属性,则可以使用非常简单的代码来完成。
来自 提升文档:
1)投掷版本(GET):
ptree pt;
/* ... */
float v = pt.get<float>("a.path.to.float.value");
2)默认值版本(GET):
ptree pt;
/* ... */
float v = pt.get("a.path.to.float.value", -1.f);
3)可选版本(get_optional):
ptree pt;
/* ... */
boost::optional<float> v = pt.get_optional<float>("a.path.to.float.value");