向boost::property_tree::ptree添加未命名节点

4

我需要向boost :: property_tree :: ptree中添加未命名节点,就像它的JSON解析器为数组做的那样。然而,当我想这样做时,在运行时会出现如下断言:

  Assertion failed: !p.empty() && "Empty path not allowed for put_child.", file C:\Program Files\Boost\boost\include/boost/property_tree/detail/ptree_implementation.hpp, line 877

我会这样做

tree.add_child(name, child);

其中tree和child都是ptree-s类型,name是char*类型。

我应该如何像JSON解析器一样处理ptree-s?

2个回答

13

我认为Boost.Property_tree没有在add_childput_child中禁止空路径的充分理由。他们内部路径工具实现的根检测需要非空路径。

当添加数组元素时,您可以通过不使用它们的路径工具来解决此问题。

using boost::property_tree::ptree;
ptree pt;
pt.put_child( "path.to.array", ptree() );
auto& array = pt.get_child( "path.to.array" );
array.push_back( std::make_pair( "", ptree("foo") ) );
array.push_back( std::make_pair( "", ptree("bar") ) );
boost::property_tree::json_parser::write_json( std::cout, pt, false );
// {"path":{"to":{"array":["foo","bar"]}}}

6
我来到这里是为了解决类似的问题。花费了一些时间,最终解决了它,希望这篇文章对其他人有所帮助。
对于我来说,解决问题的关键在于记住ptree是boost :: property_tree :: ptree :: value_type的集合。因此,问题简化为“如何将一个ptree中的value_types添加到另一个ptree中”。
Ptree提供了一些value_type插入方法:
iterator push_front(const value_type &);
iterator push_back(const value_type &);
iterator insert(iterator, const value_type &);

Ptree没有const_reference typedef,因此我们无法使用back_inserter迭代器和std::copy。但是我们可以使用绑定函数和std::for_each。

#include <algorithm>
#include <functional>
#include <boost/property_tree/ptree.hpp>

using namespace std;
using namespace boost::property_tree;

...

ptree child;
child.put("Value1", 1);
child.put("Value2", 2);

ptree parent;
std::for_each(child.begin(),
              child.end(),
              std::bind(&ptree::push_back, &parent, placeholders::_1));

现在,如果将父级输出为XML,则会包含以下内容:
<Value1>1</Value1>
<Value2>2</Value2>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接