Search code examples
c++jsonrapidjson

How to retrieve key-value data in JSON file using rapidjson C++?


I have received a JSON string as follow:

{
    "ret":"xxx",
    "error": [
        {
            "errors": {"0":"0.2", "1":"0.3" }
        },
        {
            "errors": {"2":"0.2", "3":"0.4" }
        }
    ]
}

I have written code to get all other values but I cannot figure out how to get the errors field. I have noticed that errors field is a key-value hash-like object. But the question is that all the keys in this hash-like object is changing.

I have found this question. It is using the MemberIterator, however when I use this function, there is always a error.

Some of my code is here:

  ret = "{\"ret\":\"101\",\"error\":[{\"errortype\":\"A0001\",\"errorstroke\":{\"0\":\"0.2\",\"1\":\"0.3\"}},{\"errortype\":\"A0021\",\"errorstroke\":{\"0\":\"0.2\",\"1\":\"0.3\"}}]}" ;
  rapidjson::Document doc;
  doc.Parse <kParseDefaultFlags>( ret.c_str ());
  if(doc .HasMember( "ret")){
       string retjson = doc["ret" ].GetString();
       for ( unsigned i = 0; i < retjson. length(); ++i)
       {
           CCLog("%c\t" ,retjson. at(i ));
       }
  }
  if ( doc.HasMember ("error"))
  {
       const Value & errorjson = doc["error" ];
       for ( SizeType i = 0 ; i < errorjson .Size(); ++i )
       {
           if(errorjson [i]. HasMember("errortype" )){
                string errortype = errorjson[i ]["errortype"]. GetString();
           }
           if(errorjson [i]. HasMember("errorstroke" )){
                for ( Value::ConstValueIterator iter = errorjson[i ]["errorstroke"]. onBegin; iter != errorjson[i ]["errorstroke"]. onEnd(); ++iter)
                {
                     for ( Value::MemberIterator m = iter->MemberBegin (); m != iter->MemberEnd (); ++ m)
                     {

                     }
                }
           }
       }
  }

The error occurs in Value::MemberIterator. How can I solve it or is there some problem in JSON structure design?


Solution

  • Finally I found a solution to get the key-value data using rapidjson. I found ConstMemberIterator is used for iterator for iterating in object. Suppose membersObject is a JSON object with key-value data. I can retrieve data like this.

    const rapidjson::Value& membersObject;
    for(rapidjson::Value::ConstMemberIterator it=membersObject.MemberBegin(); it != membersObject.MemberEnd(); it++) {
        cout << it->name << endl;
        cout << it->value << endl;
    }
    

    So my final program is like this:

    string ret = "{\"ret\":\"101\",\"error\":[{\"errortype\":\"A0001\",\"errorstroke\":{\"0\":\"0.2\",\"1\":\"0.3\"}},{\"errortype\":\"A0021\",\"errorstroke\":{\"0\":\"0.2\",\"1\":\"0.3\"}}]}";
    rapidjson::Document doc;
    doc.Parse<kParseDefaultFlags>(ret.c_str());
    if(doc.HasMember("ret")){
        string retjson = doc["ret"].GetString();
        for (unsigned i = 0; i < retjson.length(); ++i)
        {
            printf("%c\t",retjson.at(i));
            cout << retjson << endl;
        }
    }
    if (doc.HasMember("error"))
    {
        const Value& errorjson = doc["error"];
        for (SizeType i = 0 ; i < errorjson.Size(); ++i)
        {
            if(errorjson[i].HasMember("errortype")){
                string errortype = errorjson[i]["errortype"].GetString();
            }
            if(errorjson[i].HasMember("errorstroke")){
                const Value& et = errorjson[i]["errorstroke"];
                for (Value::ConstMemberIterator iter = et.MemberBegin(); iter != et.MemberEnd(); ++iter)
                {
                    printf("%s\t",iter->name.GetString());
                    printf("%s\t",iter->value.GetString());
                }
            }
        }
    }