【问题标题】:Parse JSON array as std::string with Boost ptree使用 Boost ptree 将 JSON 数组解析为 std::string
【发布时间】:2023-04-06 07:41:02
【问题描述】:

我有这段代码,我需要解析/或获取 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 [{ "name" : "test" }] 检索的“东西”

但是stuff 上面的代码只是返回空字符串。有什么问题

【问题讨论】:

  • [OT]:在这里使用原始字符串的好地方:ss = R"({ "id":"123", "number":"456", "stuff":[{"name":"test"}] })".

标签: c++ boost


【解决方案1】:

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

docs

  • JSON 数组映射到节点。每个元素都是一个名称为空的子节点。如果一个节点同时具有已命名和未命名的子节点,则无法将其映射到 JSON 表示形式。

Live On 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 是的。 write_json(some_stream, pt.get_child("stuff"));。将some_stream 设为std::ostringstream,以便您可以使用some_stream.str() 获取文本
  • @sehe 我想在没有 auto& e for 循环的情况下做到这一点。我们不能像 pt.get_child("stuff").name[0] 那样访问元素吗?它给出了值测试。
【解决方案2】:

由于"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;
    }
}

【讨论】:

    【解决方案3】:

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

    是否有可能得到像 '[{ "name" : "some" }, { "name" : "stuffs" }]'

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

    f.g.

    #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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-28
      • 1970-01-01
      • 2019-09-04
      • 1970-01-01
      • 2015-12-16
      • 1970-01-01
      • 2020-11-18
      相关资源
      最近更新 更多