添加未命名节点来增强::property_tree::ptree。

时间:2022-06-17 20:02:16

I need to add unnamed nodes to a boost::property_tree::ptree just like it's JSON parser does for arrays. However when I want to do it I get such assertion during runtime:

我需要将未命名节点添加到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

I do it like

我做喜欢

tree.add_child(name, child);

where tree and child are both ptree-s and name char*.

树和子都是ptree和name char*。

How could I do it like the JSON parser for ptree-s does?

我怎么能像ptree的JSON解析器那样做呢?

2 个解决方案

#1


12  

I don't think Boost.Property_tree has a good reason for disallowing empty paths in add_child or put_child. The way root detection is implemented in their internal path utilities requires non-empty paths.

我不认为提升。Property_tree有一个很好的理由来禁止add_child或put_child中的空路径。在其内部路径实用程序中实现根检测的方式需要非空路径。

You can get around this by not using their pathing utilities when adding array elements.

在添加数组元素时,您可以不使用它们的pathing实用程序来解决这个问题。

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"]}}}

#2


6  

I landed here trying to figure out a similar problem. It took me a while to solve it, so hopefully this post helps others.

我降落在这里,试图找出一个类似的问题。我花了一段时间来解决它,所以希望这篇文章能帮助别人。

For me, the key to solving the problem was remembering that a ptree is a collection of boost::property_tree::ptree::value_type. So the problem reduces to "how can I add the value_types from one ptree into another".

对于我来说,解决这个问题的关键是记住,ptree是boost的集合:property_tree::ptree::value_type。因此,问题就变成了“我如何将一个ptree中的value_types添加到另一个ptree中”。

Ptree provides a few methods for value_type insertion:

Ptree为value_type插入提供了一些方法:

iterator push_front(const value_type &);
iterator push_back(const value_type &);
iterator insert(iterator, const value_type &);

Ptree doesn't have a const_reference typedef, so we cannot make use of std::copy with back_inserter iterator. But we can use std::for_each with a bound function.

Ptree没有const_reference typedef,因此我们不能使用std::使用back_inserter迭代器复制。但是我们可以使用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));

Now if parent is output as XML it would contain:

如果父类作为XML输出,它将包含:

<Value1>1</Value1>
<Value2>2</Value2>

#1


12  

I don't think Boost.Property_tree has a good reason for disallowing empty paths in add_child or put_child. The way root detection is implemented in their internal path utilities requires non-empty paths.

我不认为提升。Property_tree有一个很好的理由来禁止add_child或put_child中的空路径。在其内部路径实用程序中实现根检测的方式需要非空路径。

You can get around this by not using their pathing utilities when adding array elements.

在添加数组元素时,您可以不使用它们的pathing实用程序来解决这个问题。

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"]}}}

#2


6  

I landed here trying to figure out a similar problem. It took me a while to solve it, so hopefully this post helps others.

我降落在这里,试图找出一个类似的问题。我花了一段时间来解决它,所以希望这篇文章能帮助别人。

For me, the key to solving the problem was remembering that a ptree is a collection of boost::property_tree::ptree::value_type. So the problem reduces to "how can I add the value_types from one ptree into another".

对于我来说,解决这个问题的关键是记住,ptree是boost的集合:property_tree::ptree::value_type。因此,问题就变成了“我如何将一个ptree中的value_types添加到另一个ptree中”。

Ptree provides a few methods for value_type insertion:

Ptree为value_type插入提供了一些方法:

iterator push_front(const value_type &);
iterator push_back(const value_type &);
iterator insert(iterator, const value_type &);

Ptree doesn't have a const_reference typedef, so we cannot make use of std::copy with back_inserter iterator. But we can use std::for_each with a bound function.

Ptree没有const_reference typedef,因此我们不能使用std::使用back_inserter迭代器复制。但是我们可以使用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));

Now if parent is output as XML it would contain:

如果父类作为XML输出,它将包含:

<Value1>1</Value1>
<Value2>2</Value2>