【问题标题】:Parse an array of objects in C++ using rapidjson使用 rapidjson 解析 C++ 中的对象数组
【发布时间】:2018-04-26 21:12:50
【问题描述】:

我正在尝试用 c++ 解析以下 JSON 文件。我想遍历 'attributes' 数组并获取 string:'value' 的值,以获得该属性对象的 string:'name' 的特定值。例如:我想解析这个 JSON 文件并获取“质量”的“值”。

{
"active": true,
"apiTier": 0,
"attributes": [
    {
        "description": "Given in the datasheet as '0.33 kg (0.73 lbm)'.",
        "maximumValue": "",
        "measurementUnit": "kg",
        "minimumValue": "",
        "name": "mass",
        "productConfiguration": "base",
        "value": "0.33"
    },    
    {
        "description": "",
         "maximumValue": "",
        "measurementUnit": "",
        "minimumValue": "",
        "name": "propellant-type",
        "productConfiguration": "base",
        "value": "hydrazine"
    },
    {
        "description": "Given in the datasheet as 'Thrust/Steady State' and the specified value is also reported as '(0.05-0.230) lbf'.",
        "maximumValue": "1.02",
        "measurementUnit": "N",
        "minimumValue": "0.22",
        "name": "thrust",
        "productConfiguration": "base",
        "value": ""
    }
]

我正在尝试在 C++ 中使用 rapidjson 库来解析 JSON 文件。下面是我解析 JSON 文件的实现。我想做的是在for循环中,对于字符串“名称”的特定“值”(例如:质量),获取字符串的其他“值”,例如“最大值”、“最小值”、“值” '等等。

#include <fstream>
#include <sstream>
#include <string>
#include <rapidjson/document.h>

int main()
{
   std::ifstream inputFile( "/path/to/json/file/" );
   std::stringstream jsonDocumentBuffer;
   std::string inputLine;

   while ( std::getline( inputFile, inputLine ) )
   {
      jsonDocumentBuffer << inputLine << "\n";
   }
   rapidjson::Document config;
   config.Parse( jsonDocumentBuffer.str( ).c_str( ) );



   assert(config.IsObject()); 

   const rapidjson::Value& attributes   = config["attributes"];
   assert(attributes.IsArray()); 

   int counter = 0; 

   for (rapidjson::Value::ConstValueIterator itr = attributes.Begin(); itr != attributes.End(); ++itr) 
   {
      const rapidjson::Value& attribute = *itr;
      assert(attribute.IsObject()); // each attribute is an object
      for (rapidjson::Value::ConstMemberIterator itr2 = attribute.MemberBegin(); itr2 != attribute.MemberEnd(); ++itr2) 
      {
         std::cout << itr2->name.GetString() << " : " << itr2->value.GetString() << std::endl;
      }
}

编辑 1:我找到了一个关于如何遍历属性数组并访问属性数组中每个对象的每个字符串及其值的解决方案。但是,我想做的是获取任何字符串的值(例如:'maximumValue'、'minimumValue'、'Value')等,以获得字符串'name'的特定值(例如:mass)。

【问题讨论】:

    标签: c++ rapidjson


    【解决方案1】:

    如果您只想获取选定属性的指定属性,可以使用以下函数:

    #include <iostream>
    #include <vector>
    #include <map>
    #include "rapidjson/document.h"
    
    std::map<std::string, std::string> mapForAttributeThatMatchesName(const rapidjson::Value& attributes, const std::string& findMemberName, const std::string& findMemberValue, const std::vector<std::string>& keysToRetrieve) {
    
        std::map<std::string, std::string> result;
        for (rapidjson::Value::ConstValueIterator itr = attributes.Begin(); itr != attributes.End(); ++itr) {
    
            const rapidjson::Value::ConstMemberIterator currentAttribute = itr->FindMember(findMemberName.c_str());
            if (currentAttribute != itr->MemberEnd() && currentAttribute->value.IsString()) {
    
                if (currentAttribute->value == findMemberValue.c_str()) {
    
                    for (auto &keyToRetrieve : keysToRetrieve) {
    
                        const rapidjson::Value::ConstMemberIterator currentAttributeToReturn = itr->FindMember(keyToRetrieve.c_str());
                        if (currentAttributeToReturn != itr->MemberEnd() && currentAttributeToReturn->value.IsString()) {
    
                            result[keyToRetrieve] = currentAttributeToReturn->value.GetString();
                        }
                    }
                    return result;
                }
            }
        }
        return result;
    }
    

    你可以这样测试它:

    const rapidjson::Value& attributes = config["attributes"];
    assert(attributes.IsArray());
    
    std::vector<std::string> keysToRetrieve = {"maximumValue", "minimumValue"};
    std::map<std::string, std::string> mapForResult = mapForAttributeThatMatchesName(attributes, "name", "mass", keysToRetrieve);
    for (auto &mapItem : mapForResult) {
    
        std::cout << mapItem.first << ":" << mapItem.second << "\n";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多