使用属性树在Boost中创建JSON数组

Chr*_*hio 66 c++ json boost boost-propertytree

我正在尝试使用boost属性树创建一个JSON数组.

文件说:"JSON数组被映射到节点的每个元素与空名称的子节点."

所以我想创建一个空名称的属性树,然后调用write_json(...)以获取数组.但是,文档没有告诉我如何创建未命名的子节点.我试过了ptree.add_child("", value),但这会产生:

Assertion `!p.empty() && "Empty path not allowed for put_child."' failed
Run Code Online (Sandbox Code Playgroud)

文档似乎没有解决这一点,至少不能以任何方式解决.有人可以帮忙吗?

小智 106

简单数组:

#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);
Run Code Online (Sandbox Code Playgroud)

结果是:

{
    "MyArray":
    [
        "1",
        "2",
        "3"
    ]
}
Run Code Online (Sandbox Code Playgroud)

对象上的数组:

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);
Run Code Online (Sandbox Code Playgroud)

结果是:

{
    "testkey": "testvalue",
    "MyArray":
    [
        {
            "childkeyA": "1",
            "childkeyB": "2"
        },
        {
            "childkeyA": "3",
            "childkeyB": "4"
        },
        {
            "childkeyA": "5",
            "childkeyB": "6"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助

  • 请注意,数字编码为字符串而不是数字. (5认同)
  • 使用boost库时,我找不到一个好的解决方案.我切换到了rapidjson. (3认同)

Mic*_*son 20

你需要做的就是这件乐趣.这是来自记忆,但这样的事情对我有用.

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 ) );
Run Code Online (Sandbox Code Playgroud)

但要注意json解析和写入中有几个错误.其中几个我已经提交了错误报告 - 没有回复:(

编辑:解决它对错误序列化的关注{"":"","":"""}

仅当数组是根元素时才会发生这种情况.boost ptree writer将所有根元素视为对象 - 绝不是数组或值.这是由boost/property_tree/detail/json_parser_writer.hpp中的以下行引起的

else if (indent > 0 && pt.count(Str()) == pt.size())
Run Code Online (Sandbox Code Playgroud)

摆脱"缩进> 0 &&"将允许它正确地写入数组.

如果您不喜欢产生多少空间,可以使用我在这里提供的补丁


Yuk*_*iko 11

当开始使用属性树来表示JSON结构时,我遇到了类似的问题,我没有解决.另请注意,从文档中,属性树不完全支持类型信息:

JSON值映射到包含该值的节点.但是,所有类型信息都丢失了; 数字,以及文字"null","true"和"false"只是简单地映射到它们的字符串形式.

在学习之后,我切换到了更完整的JSON实现JSON Spirit.该库使用Boost Spirit进行JSON语法实现,并完全支持包含数组的JSON.

我建议你使用另一种C++ JSON实现.


2Ni*_*meo 6

在我的情况下,我想将一个数组添加到一个或多或少的任意位置,因此,像迈克尔的答案一样,创建一个子树并用数组元素填充它:

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))
}
Run Code Online (Sandbox Code Playgroud)

填充子项后,使用put_child()add_child()函数将整个子树添加到目标树中,如下所示...

targetTree.put_child(ptree::path_type("target.path.to.array"),arrayChild)
Run Code Online (Sandbox Code Playgroud)

put_child函数为参数获取路径和树,并将arrayChild"移植"到targetTree中