2

I have the following JSON object

{  
   "prog":[  
      {  
         "iUniqueID":1,
         "bGroup":1,
         "inFiles":[  
            {  
               "sFileType":"Zonal Data 1",
               "bScenarioSpecific":0,
               "pos":{  
                  "x1":1555,
                  "y1":-375,
                  "x2":1879,
                  "y2":-432
               }
            },
            {  
               "sFileType":"Record File",
               "bScenarioSpecific":0,
               "pos":{  
                  "x1":1555,
                  "y1":-436,
                  "x2":1879,
                  "y2":-493
               }
            }
         ],
         "outFiles":[  
            {  
               "sFileType":"Record File 1",
               "bScenarioSpecific":1,
               "pos":{  
                  "x1":2344,
                  "y1":-405,
                  "x2":2662,
                  "y2":-462
               }
            }
         ]
      },
      {  
         "iUniqueID":2,
         "bGroup":1,
         "inFiles":[  
            {  
               "sFileType":"Matrix File 1",
               "bScenarioSpecific":0,
               "pos":{  
                  "x1":98,
                  "y1":-726,
                  "x2":422,
                  "y2":-783
               }
            },
            {  
               "sFileType":"Matrix File 2",
               "bScenarioSpecific":0,
               "pos":{  
                  "x1":98,
                  "y1":-787,
                  "x2":422,
                  "y2":-844
               }
            }
         ],
         "outFiles":[  
            {  
               "sFileType":"Record File 1",
               "bScenarioSpecific":1,
               "pos":{  
                  "x1":887,
                  "y1":-966,
                  "x2":1205,
                  "y2":-1023
               }
            }
         ]
      }
   ]
}

How can I iteratively access the x1 of objects inside "inFiles"? Or in general, how can I access the values stored in sub-array and sub-objects using rapidjson. Here is what I have so far

const Value& prog = document["prog"];

assert(prog.IsArray());

for (rapidjson::Value::ConstValueIterator itr = prog.Begin(); itr != prog.End(); ++itr) {

}

I have tried a variety of things but my code does not compile, therefore I felt like it would need be productive to add it to the description of the issue.

Raymond Kalonji
  • 345
  • 3
  • 14
  • please provide an [mcve] and the exact compilation command and error messages you are receiving. Also, the contents of the JSON are irrelevant if the code doesn't compile. – xaxxon Aug 11 '18 at 03:10
  • How about `jq`? `cat f.json | jq .prog[].inFiles[].pos.x1` – Martin York Aug 11 '18 at 05:09

3 Answers3

3

Here is what ended up working

const Value& prog = d["prog"];
for (Value::ConstValueIterator p = prog.Begin(); p != prog.End(); ++p) {
    std:cout << (*p)["iUniqueID"].GetInt();
    const Value& inFiles = (*p)["inFiles"];
    for (Value::ConstValueIterator inFile = inFiles.Begin(); inFile != prog.End(); ++inFile) {
        std::cout << (*inFile)["sFileType"].GetString() << std::endl;
        std::cout << (*inFile)["pos"]["x1"].GetInt() << std::endl;
    }
}

The post here helped tremendously.

Raymond Kalonji
  • 345
  • 3
  • 14
1

Here is a way you can iterate over the subarrays inside each array. Using ranged-for loop instead of iterator.

rapidjson::Document doc;
doc.Parse(str); //the one shown in the question


for (auto const& p : doc["prog"].GetArray()) {
    std::cout << p["iUniqueID"].GetInt() << std::endl;
    for (auto const& in : p["inFiles"].GetArray()) {
        std::cout << in["sFileType"].GetString() << std::endl;
        std::cout << in["pos"]["x1"].GetInt() << std::endl;
    }
}

Hope this helps.

Wander3r
  • 1,801
  • 17
  • 27
  • Thanks for helping. Now, the project is being compiled with Visual Studio 2010 so when I try the above, I get the error "cannot deduce 'auto' type (initializer required)". Any idea on how to do the same thing using iterators? – Raymond Kalonji Aug 12 '18 at 13:06
  • Before I can edit, another person has posted the same code using iterators. You can check that. – Wander3r Aug 12 '18 at 16:32
  • Using `auto` in an example like this is not helpful. What is the type of `p` and `in`? – lmat - Reinstate Monica Sep 12 '22 at 12:54
0

If you want to iterate through the properties of an object, you can use a Range-based for loop on rapidjson::Object or rapidjson::ConstObject:

if (value.IsObject()) {
    for (auto &item : value.GetObject()) {
        std::string propertyKey = item.name.GetString();
        auto &propertyValue = item.value;

        // [...]
    }
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174