使用 boost 属性树读取子 json

问题描述

我需要读取 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
            }
          }    }  ]
        }

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

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 属性树不是 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","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}}