使用Boost ptree将JSON数组解析为std::string

5

我有这段代码,需要解析或获取JSON数组作为std::string以便在应用程序中使用。

std::string ss = "{ \"id\" : \"123\", \"number\" : \"456\", \"stuff\" : [{ \"name\" : \"test\" }] }";

ptree pt2;
std::istringstream is(ss);
read_json(is, pt2);
std::string id = pt2.get<std::string>("id");
std::string num= pt2.get<std::string>("number");
std::string stuff = pt2.get<std::string>("stuff"); 

需要的是像这样作为std :: string检索"stuff"[{ "name" : "test" }]

然而,上述代码中 stuff 只返回空字符串。可能出了什么问题?


[OT]: 在这里使用原始字符串的好处:ss = R"({ "id":"123", "number":"456", "stuff":[{"name":"test"}] })" - Jarod42
3个回答

7

数组被表示为具有许多 "" 键的子节点:

文档

  • JSON 数组被映射到节点。每个元素都是一个带空名称的子节点。如果一个节点既有命名的子节点又有未命名的子节点,则无法映射到 JSON 表示。

在 Coliru 上实时运行

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using boost::property_tree::ptree;

int main() {
    std::string ss = "{ \"id\" : \"123\", \"number\" : \"456\", \"stuff\" : [{ \"name\" : \"test\" }, { \"name\" : \"some\" }, { \"name\" : \"stuffs\" }] }";

    ptree pt;
    std::istringstream is(ss);
    read_json(is, pt);

    std::cout << "id:     " << pt.get<std::string>("id") << "\n";
    std::cout << "number: " << pt.get<std::string>("number") << "\n";
    for (auto& e : pt.get_child("stuff")) {
        std::cout << "stuff name: " << e.second.get<std::string>("name") << "\n";
    }
}

打印

id:     123
number: 456
stuff name: test
stuff name: some
stuff name: stuffs

能否像 '[{ "name" : "some" }, { "name" : "stuffs" }]' 这样获取它? - xkm
1
@xkm 是的。write_json(some_stream, pt.get_child("stuff"));。将 some_stream 设为 std::ostringstream,这样你就可以使用 some_stream.str() 来获取文本。 - sehe
@sehe 我想不使用自动和e循环来完成它。我们能否通过pt.get_child("stuff").name[0]访问元素并获得值test。 - user3217310

1

继续@sehe的回答,与@xkm提出的问题有关

是否可以得到像 '[{"name":"some"},{"name":"stuffs"}]' 这样的结果?

是的,你可以。只需使用一个“未命名”的键,这意味着带有空字符串的键。

例如:

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include <iostream>

using boost::property_tree::ptree;

int main()
{
    std::stringstream ss;
    ss << R"([{"a": 5}, {"a": 9}])";

    ptree pt;
    read_json(ss, pt);
    for (auto& item : pt.get_child(""))
       std::cout << "value is " << item.second.get<int>("a") << std::endl;
}

1

由于"stuff"是一个数组,您可以迭代它的元素,这些元素是字典。然后您可以迭代字典的元素,这些元素是键值对:

for (const auto& dict : pt2.get_child("stuff")) {
    for (const auto& kv : dict.second) {
        std::cout << "key = " << kv.first << std::endl;
        std::cout << "val = " << kv.second.get_value<std::string>() << std::endl;
    }
}

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