Json: Trying to retrieve data from nested objects

Created on 5 Apr 2018  路  7Comments  路  Source: nlohmann/json

Hi, I'm trying to map data from a Json file to individual objects in order to sort them and perform other operations on them. However, the data structure required is quite complex and makes it hard to navigate.
Here is a snippet of the Json file:

{
  "items":
  {
    "item":
    [
      {
        "id": "0001",
        "type": "donut",
        "name": "Cake",
        "ppu": 0.55,
        "batters":
        {
          "batter":
          [
            { "id": "1001", "type": "Regular" },
            { "id": "1002", "type": "Chocolate" },
            { "id": "1003", "type": "Blueberry" },
            { "id": "1004", "type": "Devil's Food" }
          ]
        },
        "topping":
        [
          { "id": "5001", "type": "None" },
          { "id": "5002", "type": "Glazed" },
          { "id": "5005", "type": "Sugar" },
          { "id": "5007", "type": "Powdered Sugar" },
          { "id": "5006", "type": "Chocolate with Sprinkles" },
          { "id": "5003", "type": "Chocolate" },
          { "id": "5004", "type": "Maple" }
        ]
      },
      [...] Other items could be there
    ]
  }
}

I cannot change the way it is organised. However, I cannot figure out how to properly get every element and extract it.

My current code:

ifstream input("sample.json");

    json json1;

    input >> json1;

    json json2 = json1["items"]["item"];

    for ( auto& item : json2.get<json::object_t>() ){
        Item *tempItem = new Item();

        tempItem->setId(item.at("id"));
        tempItem->setName(item.at("name"));
        tempItem->setType(item.at("type"));
        tempItem->setId(item.at("ppu"));
        //Trying to go in the array batters
        object_t temp_obj = item.at("batters");

        items.push_back(new Item());
    }

Note: Even then I get an error because json2.get<json::object_t>() returns a pair<>.

Thanks in advance!

question proposed fix

Most helpful comment

You could try

for (const auto& item : json1["items"]["item"])
{
    // check if item["batters"]["batter"] exists
    if (item.find("batters") != item.end() and
        item["batters"].find("batter") != item["batters"].end())
    {
        for (const auto& batter : item["batters"]["batter"])
        {
            std::cout << batter["id"] << ", " << batter["type"] << std::endl;
        }
    }

    // check if item["topping"] exists
    if (item.find("topping") != item.end())
    {
        for (const auto& batter : item["topping"])
        {
            std::cout << batter["id"] << ", " << batter["type"] << std::endl;
        }
    }
}

All 7 comments

You could try

for (const auto& item : json1["items"]["item"])
{
    // check if item["batters"]["batter"] exists
    if (item.find("batters") != item.end() and
        item["batters"].find("batter") != item["batters"].end())
    {
        for (const auto& batter : item["batters"]["batter"])
        {
            std::cout << batter["id"] << ", " << batter["type"] << std::endl;
        }
    }

    // check if item["topping"] exists
    if (item.find("topping") != item.end())
    {
        for (const auto& batter : item["topping"])
        {
            std::cout << batter["id"] << ", " << batter["type"] << std::endl;
        }
    }
}

This does answer my initial question, but now I get a parsing error.

    ifstream input;
    input.open(R"(C:\Users\Etienne\Documents\GitHub\Collaboration\assingment 5\sample.json)");

    json json1;

    input >> json1; //Error

    cout<<"after parse";

    json json2 = json1["items"]["item"];

For an unknown reason it doesn't accept the parsing.

What is the error?

It just stops, no error or anything. It tried printing after each statement and it happens at the JSON parsing.

Can you check whether you can print the file content? Can you run the code in a debugger?

After a few hours trying to debug, I finally got it to compile properly (reinstalled MinGW, changed my paths, etc.). The above code that @nlohmann wrote is accurate and works fine!
Thanks for your support and quick answers

Thanks for checking back!

Was this page helpful?
0 / 5 - 0 ratings