使用属性树在Boost中创buildJSON数组
我正在尝试使用boost属性树创build一个JSON数组。
该文档说:“JSON数组映射到节点。每个元素是一个空名称的子节点。
所以我想创build一个名称为空的属性树,然后调用write_json(...)
来获取数组。 但是,文档不告诉我如何创build未命名的子节点。 我试过ptree.add_child("", value)
,但是这样会产生:
Assertion `!p.empty() && "Empty path not allowed for put_child."' failed
文件似乎没有解决这一点,至less不以我能想出的任何方式。 谁能帮忙?
简单的数组:
#include <boost/property_tree/ptree.hpp> using boost::property_tree::ptree; ptree pt; ptree children; ptree child1, child2, child3; child1.put("", 1); child2.put("", 2); child3.put("", 3); children.push_back(std::make_pair("", child1)); children.push_back(std::make_pair("", child2)); children.push_back(std::make_pair("", child3)); pt.add_child("MyArray", children); write_json("test1.json", pt);
结果是:
{ "MyArray": [ "1", "2", "3" ] }
在对象上的数组:
ptree pt; ptree children; ptree child1, child2, child3; child1.put("childkeyA", 1); child1.put("childkeyB", 2); child2.put("childkeyA", 3); child2.put("childkeyB", 4); child3.put("childkeyA", 5); child3.put("childkeyB", 6); children.push_back(std::make_pair("", child1)); children.push_back(std::make_pair("", child2)); children.push_back(std::make_pair("", child3)); pt.put("testkey", "testvalue"); pt.add_child("MyArray", children); write_json("test2.json", pt);
结果是:
{ "testkey": "testvalue", "MyArray": [ { "childkeyA": "1", "childkeyB": "2" }, { "childkeyA": "3", "childkeyB": "4" }, { "childkeyA": "5", "childkeyB": "6" } ] }
希望这可以帮助
你需要做的是这一块的乐趣。 这是来自记忆,但这样的事情对我很有用。
boost::property_tree::ptree root; boost::property_tree::ptree child1; boost::property_tree::ptree child2; // .. fill in children here with what you want // ... ptree.push_back( std::make_pair("", child1 ) ); ptree.push_back( std::make_pair("", child2 ) );
但是请注意jsonparsing和写入中存在一些错误。 其中几个我已经提交了错误报告 – 没有回应:(
编辑:解决关于它不正确的序列化为{“”:“”,“”:“”}
只有当数组是根元素时才会发生这种情况。 boost ptree编写器将所有根元素视为对象 – 从不是数组或值。 这是由boost / propert_tree / detail / json_parser_writer.hpp中的以下行引起的
else if (indent > 0 && pt.count(Str()) == pt.size())
摆脱“indent> 0 &&”将允许它正确地写入数组。
如果你不喜欢产生多less空间,你可以使用我在这里提供的补丁
当开始使用Property Tree来表示一个JSON结构时,我遇到了类似的问题,我没有解决。 还请注意,从文档中,属性树不完全支持types信息:
JSON值被映射到包含该值的节点。 但是,所有types的信息都丢失了; 数字以及文字“null”,“true”和“false”只是映射到它们的stringforms。
学习完这些之后,我切换到了更完整的JSON实现JSON Spirit 。 该库为JSON语法实现使用了Boost Spirit,并完全支持包括数组的JSON。
我build议你使用另一种C ++ JSON实现。
在我的情况下,我想添加一个数组到一个或多或less的任意位置,所以,就像迈克尔的回答一样,创build一个子树并用数组元素填充它:
using boost::property_tree::ptree; ptree targetTree; ptree arrayChild; ptree arrayElement; //add array elements as desired, loop, whatever, for example for(int i = 0; i < 3; i++) { arrayElement.put_value(i); arrayChild.push_back(std::make_pair("",arrayElement)) }
当孩子被填充时,使用put_child()
或add_child()
函数将整个子树添加到目标树,像这样…
targetTree.put_child(ptree::path_type("target.path.to.array"),arrayChild)
put_child函数为参数提供一个path和一个树,并将arrayChild“嫁接”到targetTree中
另一个例子,基于以前的。
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/json_parser.hpp> #include <vector> #include <string> #include <iostream> int main() { boost::property_tree::ptree root; std::vector<std::string> simple_array{"boost", "ptree", "example"}; root.add("number", 20); auto& simple_array_pt = root.add_child("simple_array", boost::property_tree::ptree()); for (const std::string& str: simple_array) { boost::property_tree::ptree str_pt; str_pt.put("", str); simple_array_pt.push_back(std::make_pair("", str_pt)); } boost::property_tree::write_json(std::cout, root); return 0; }
汇编:
g++ -std=c++11 -lboost_system main.cpp
这里是输出:
{ "number": "20", "simple_array": [ "boost", "ptree", "example" ] }