And*_*dry 19 c++ xml iterator boost-propertytree
我知道正在接近提升属性树,并发现它是c ++编程的boost库的一个很好的特性.
好吧,我有一个疑问?如何使用迭代器或类似方法迭代属性树?
在参考中,只有一个浏览树的例子:
BOOST_FOREACH
Run Code Online (Sandbox Code Playgroud)
但仅此而已吗?像stl一样的容器?谈到代码质量,这将是一个更好的解决方案....
Ric*_*ich 27
这是我经过多次实验后想出来的.我想在社区分享它,因为我找不到我想要的东西.每个人似乎只是发布了增强文档的答案,我发现这些文档是不够的.无论如何:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <string>
#include <iostream>
using namespace std;
using boost::property_tree::ptree;
string indent(int level) {
string s;
for (int i=0; i<level; i++) s += " ";
return s;
}
void printTree (ptree &pt, int level) {
if (pt.empty()) {
cerr << "\""<< pt.data()<< "\"";
}
else {
if (level) cerr << endl;
cerr << indent(level) << "{" << endl;
for (ptree::iterator pos = pt.begin(); pos != pt.end();) {
cerr << indent(level+1) << "\"" << pos->first << "\": ";
printTree(pos->second, level + 1);
++pos;
if (pos != pt.end()) {
cerr << ",";
}
cerr << endl;
}
cerr << indent(level) << " }";
}
return;
}
int main(int, char*[]) {
// first, make a json file:
string tagfile = "testing2.pt";
ptree pt1;
pt1.put("object1.type","ASCII");
pt1.put("object2.type","INT64");
pt1.put("object3.type","DOUBLE");
pt1.put("object1.value","one");
pt1.put("object2.value","2");
pt1.put("object3.value","3.0");
write_json(tagfile, pt1);
ptree pt;
bool success = true;
try {
read_json(tagfile, pt);
printTree(pt, 0);
cerr << endl;
}catch(const json_parser_error &jpe){
//do error handling
success = false
}
return success;
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
rcook@rzbeast (blockbuster): a.out
{
"object1":
{
"type": "ASCII",
"value": "one"
},
"object2":
{
"type": "INT64",
"value": "2"
},
"object3":
{
"type": "DOUBLE",
"value": "3.0"
}
}
rcook@rzbeast (blockbuster): cat testing2.pt
{
"object1":
{
"type": "ASCII",
"value": "one"
},
"object2":
{
"type": "INT64",
"value": "2"
},
"object3":
{
"type": "DOUBLE",
"value": "3.0"
}
}
Run Code Online (Sandbox Code Playgroud)
And*_*hko 17
BOOST_FOREACH只是迭代的一种便捷方式,可以通过迭代器,begin()和end()完成
Your_tree_type::const_iterator end = tree.end();
for (your_tree_type::const_iterator it = tree.begin(); it != end; ++it)
...
Run Code Online (Sandbox Code Playgroud)
在C++ 11中它是:
for (auto it: tree)
...
Run Code Online (Sandbox Code Playgroud)
我最近遇到了这个问题并且发现答案不完整我的需要,所以我想出了这个简短而又甜蜜的片段:
using boost::property_tree::ptree;
void parse_tree(const ptree& pt, std::string key)
{
std::string nkey;
if (!key.empty())
{
// The full-key/value pair for this node is
// key / pt.data()
// So do with it what you need
nkey = key + "."; // More work is involved if you use a different path separator
}
ptree::const_iterator end = pt.end();
for (ptree::const_iterator it = pt.begin(); it != end; ++it)
{
parse_tree(it->second, nkey + it->first);
}
}
Run Code Online (Sandbox Code Playgroud)
需要注意的是,除根节点外的任何节点都可以包含数据和子节点.该if (!key.empty())
位将获取除根节点之外的所有数据,我们也可以开始构建节点子节点的循环路径(如果有的话).
你可以通过调用开始解析parse_tree(root_node, "")
,当然你需要在这个函数中做一些事情来使它值得做.
如果您正在进行一些不需要FULL路径的解析,只需删除nkey
变量及其操作,然后传递it->first
给递归函数.