-1

I have the following json:

{
    "laureates": [{
        "id": "1",
        "firstname": "Wilhelm Conrad",
        "surname": "Röntgen",
        "born": "1845-03-27",
        "died": "1923-02-10",
        "bornCountry": "Prussia (now Germany)",
        "bornCountryCode": "DE",
        "bornCity": "Lennep (now Remscheid)",
        "diedCountry": "Germany",
        "diedCountryCode": "DE",
        "diedCity": "Munich",
        "gender": "male",
        "prizes": [{
            "year": "1901",
            "category": "physics",
            "share": "1",
            "motivation": "\"in recognition of the extraordinary services he has rendered by the discovery of the remarkable rays subsequently named after him\""
        }]
    }]
}

I have tried this:

bool ok = reader.parse(txt, root, false);

    if(! ok)
    {
        std::cout << "failed parse\n";
    }

std::vector<std::string> keys = root.getMemberNames();

for (std::vector<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it)
    {
        if (root[*it].isString())
        {
            std::string value = root[*it].asString();
            std::cout << value << std::endl;
        }
        else if (root[*it].isInt())
        {
             int value = root[*it].asInt();
             std::cout << value << std::endl;
        }
        else if (root[*it].isArray()){
            // what to do here?
        }
}

The code works fine, but the problem is when I have an array like "prizes". I can't realize how to iterate and show the values without hardcoded it.

Can anyone help me with this?

Thanks in advance.

3
  • 1
    Are you asking, "How do I tell that prizes is an array so that I know I need to iterate it?" If so, there is an is_array method in every node. Wait a sec. You're already using it. I'm now puzzled. You do pretty much what you already did in the earlier for loop, but on root[*it]. Commented May 24, 2022 at 20:39
  • Hi, thank you for you reply.Yes, I've noticed what you mean, but if I create a new vector of strings with let's call it "keys2", this is, std::vector<std::string> keys2 = root[*it].getMemberNames(); , I'm getting this error: "in Json::Value::getMemberNames(), value must be objectValue. Commented May 24, 2022 at 20:51
  • The difference here is the items in the array don't have names. You go directly after the objects. The version of jsoncpp I'm working with looks a bit different from yours, but my code would look something like for (const auto & item: root[*it].array_items()), then I operate on items in the loop body to get what I want. Commented May 24, 2022 at 21:02

1 Answer 1

0

I can't realize how to iterate and show the values without hardcoded it.

I think the problem is that you don't have a great handle on recursion or the key->value nature of JSON, because when you have an array like "prizes", you could have a nested Json object, such as an array inside an array.

You could use a recursion to handle that:

#include <jsoncpp/json/json.h>

#include <iostream>

void PrintJSONValue(const Json::Value &val) {
  if (val.isString()) {
    std::cout << val.asString();
  } else if (val.isBool()) {
    std::cout << val.asBool();
  } else if (val.isInt()) {
    std::cout << val.asInt();
  } else if (val.isUInt()) {
    std::cout << val.asUInt();
  } else if (val.isDouble()) {
    std::cout << val.asDouble();
  } else {
  }
}

void HandleJsonTree(const Json::Value &root, uint32_t depth = 0) {
  depth += 1;
  if (root.size() > 0) {
    std::cout << '\n';
    for (Json::Value::const_iterator itr = root.begin(); itr != root.end();
         itr++) {
      // print space to indicate depth
      for (int tab = 0; tab < depth; tab++) {
        std::cout << " ";
      }
      std::cout << "key: ";
      PrintJSONValue(itr.key());
      std::cout << " ";
      HandleJsonTree(*itr, depth);
    }
  } else {
    std::cout << ", value: ";
    PrintJSONValue(root);
    std::cout << "\n";
  }
}

int main(int argc, char **argv) {
  std::string json = R"###(
        {
    "laureates": [
        {
            "id": "1",
            "firstname": "Wilhelm Conrad",
            "surname": "Röntgen",
            "born": "1845-03-27",
            "died": "1923-02-10",
            "bornCountry": "Prussia (now Germany)",
            "bornCountryCode": "DE",
            "bornCity": "Lennep (now Remscheid)",
            "diedCountry": "Germany",
            "diedCountryCode": "DE",
            "diedCity": "Munich",
            "gender": "male",
            "prizes": [
                {
                    "year": "1901",
                    "category": "physics",
                    "share": "1",
                    "motivation": "in recognition of the extraordinary services he has rendered by the discovery of the remarkable rays subsequently named after him"
                }
            ]
        }
    ]
}
    )###";
  Json::Value root;
  Json::Reader reader;
  bool ok = reader.parse(json, root, false);

  if (!ok) {
    std::cout << "failed parse\n";
  }

  HandleJsonTree(root);
}

The output looks like this:

 key: laureates 
  key: 0 -- the first item of an array
   key: born , value: 1845-03-27
   key: bornCity , value: Lennep (now Remscheid)
   key: bornCountry , value: Prussia (now Germany)
   key: bornCountryCode , value: DE
   key: died , value: 1923-02-10
   key: diedCity , value: Munich
   key: diedCountry , value: Germany
   key: diedCountryCode , value: DE
   key: firstname , value: Wilhelm Conrad
   key: gender , value: male
   key: id , value: 1
   key: prizes 
    key: 0 -- the first item of an array
     key: category , value: physics
     key: motivation , value: in recognition of the extraordinary services he has rendered by the discovery of the remarkable rays subsequently named after him
     key: share , value: 1
     key: year , value: 1901
   key: surname , value: Röntgen
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.