使用 boost 属性 树读取子 json

Read a sub json using boost property tree

我需要读取 JSON 文件中的一个字段,该文件本身就是一个 JSON。我需要一次性阅读 JSON 字段。有什么办法吗?下面提供了我正在尝试阅读的示例 JSON。

enter code here
   {
      "responses": [
       { 
          "id": "1",
          "status": 200,
          "headers": {
                 "OData-Version": "4.0",
                 "Content-Type":"application/json;odata.metadata=minimal;odata.streaming=true"
           },
          "body": {        
              "createdDateTime": "2021-04-22T09:24:59.394Z",
              "displayName": "Test1",        
              "visibility": "public",        
              "isMembershipLimitedToOwners": false,
              "discoverySettings": { "showInTeamsSearchAndSuggestions": true },
              "memberSettings": {
              "allowCreateUpdateChannels": true,
              "allowCreateUpdateRemoveConnectors": true
           },
           "guestSettings": {
              "allowCreateUpdateChannels": true,
              "allowDeleteChannels": false
            },
            "messagingSettings": {
              "allowUserEditMessages": true,
              "allowChannelMentions": true
            },
            "funSettings": {
              "allowGiphy": true,
              "allowCustomMemes": true
            }
          }    }  ]
        }

我正在尝试使用下面的代码读取“正文”字段(json 在 boost::property_tree::ptree jsonBatchResponse jsonBatchResponse 中读取)。但是 strBody 是空的,它没有正确读取“正文”字段。 :

enter code here
     for (auto& v : jsonBatchResponse.get_child("responses"))
     {       
        std::string strID = v.second.get<std::string>("id", "");
        std::string strStatus = v.second.get<std::string>("status", "");
        std::string strBody = v.second.get<std::string>("body", "");
     }

看起来 v.second.getstd::string("body", "") 不是读取 JSON 字段的正确方法。有没有其他可用的方法(除了读取 JSON 值中的各个字段)?请告诉我。

正文不是字符串。

因此,获取子对象将是有序的:

for (auto const& v : jsonBatchResponse.get_child("responses")) {
    std::string  strID     = v.second.get<std::string>("id", "");
    std::string  strStatus = v.second.get<std::string>("status", "");
    ptree const& body      = v.second.get_child("body");
}

如果您使用例如

向该循环添加一些输出
    std::cout << std::quoted(strID) << "\n";
    std::cout << std::quoted(strStatus) << "\n";
    write_json(std::cout, body);

它将打印Live On Coliru

"1"
"200"
{
    "createdDateTime": "2021-04-22T09:24:59.394Z",
    "displayName": "Test1",
    "visibility": "public",
    "isMembershipLimitedToOwners": "false",
    "discoverySettings": {
        "showInTeamsSearchAndSuggestions": "true"
    },
    "memberSettings": {
        "allowCreateUpdateChannels": "true",
        "allowCreateUpdateRemoveConnectors": "true"
    },
    "guestSettings": {
        "allowCreateUpdateChannels": "true",
        "allowDeleteChannels": "false"
    },
    "messagingSettings": {
        "allowUserEditMessages": "true",
        "allowChannelMentions": "true"
    },
    "funSettings": {
        "allowGiphy": "true",
        "allowCustomMemes": "true"
    }
}

奖励:改用适当的 JSON 库

Boost 属性 Tree 不是 JSON 库,因此有很多 limitations.

相反,我建议使用 Boost JSON:

Live On Coliru

#include <boost/json.hpp>
#include <boost/json/src.hpp>
#include <iostream>

namespace json = boost::json;

extern std::string sample;

int main() {
    json::object jsonBatchResponse = json::parse(sample).as_object();

    for (auto& v : jsonBatchResponse["responses"].as_array()) {
        auto& res = v.as_object();
        json::value id  = res["id"],     // string
            status      = res["status"], // integer
            body        = res["body"];   // object
        std::cout << id << "\n";
        std::cout << status << "\n";
        std::cout << body << "\n";
    }
}

std::string sample = R"(
{
    "responses": [{
        "id": "1",
        "status": 200,
        "headers": {
            "OData-Version": "4.0",
            "Content-Type": "application/json;odata.metadata=minimal;odata.streaming=true"
        },
        "body": {
            "createdDateTime": "2021-04-22T09:24:59.394Z",
            "displayName": "Test1",
            "visibility": "public",
            "isMembershipLimitedToOwners": false,
            "discoverySettings": {
                "showInTeamsSearchAndSuggestions": true
            },
            "memberSettings": {
                "allowCreateUpdateChannels": true,
                "allowCreateUpdateRemoveConnectors": true
            },
            "guestSettings": {
                "allowCreateUpdateChannels": true,
                "allowDeleteChannels": false
            },
            "messagingSettings": {
                "allowUserEditMessages": true,
                "allowChannelMentions": true
            },
            "funSettings": {
                "allowGiphy": true,
                "allowCustomMemes": true
            }
        }
    }]
}
)";

版画

"1"
200
{"createdDateTime":"2021-04-22T09:24:59.394Z","displayName":"Test1","visibility":"public","isMembershipLimitedToOwners":false,"discoverySettings":{"showInTeamsSearchAndSuggestions":true},"memberSettings":{"allowCreateUpdateChannels":true,"allowCreateUpdateRemoveConnectors":true},"guestSettings":{"allowCreateUpdateChannels":true,"allowDeleteChannels":false},"messagingSettings":{"allowUserEditMessages":true,"allowChannelMentions":true},"funSettings":{"allowGiphy":true,"allowCustomMemes":true}}