rapid JSON fails with Assertion `IsObject()' failed

Prashant picture Prashant · Mar 8, 2016 · Viewed 7.1k times · Source

I am trying to parse the data received from a server with RapidJSON . Following is the exact string that is received:

[
  {
    "Node": "9478149a08f9",
    "Address": "172.17.0.2",
    "ServiceID": "HSS",
    "ServiceName": "HSS",
    "ServiceTags": [],
    "ServiceAddress": "",
    "ServicePort": 6666,
    "ServiceEnableTagOverride": false,
    "CreateIndex": 2855,
    "ModifyIndex": 2855
  }
]

Following is the code

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = (char *)malloc(1);  /* will be grown as needed by the realloc above */
  chunk.size = 0;    /* no data at this point */

  /* In windows, this will init the winsock stuff */
  curl_global_init(CURL_GLOBAL_ALL);

  /* get a curl handle */
  curl = curl_easy_init();
  if(curl) {
    /* First set the URL that is about to receive our POST. This URL can
       just as well be a https:// URL if that is what should receive the
       data. */
    curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8500/v1/catalog/service/HSS");
    /* Now specify the POST data */

    // Set the callbackfunction to handle the JSON string
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk);
    /* Perform the request, res will get the return code */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));

    /* always cleanup */
    curl_easy_cleanup(curl);
  }

  std::string str;
  str.assign(chunk.memory,chunk.size);

  cout<<"The string response is :"<<str<<endl;
  Document d;
  d.Parse(str.c_str());

  assert(d.IsObject());

<-- It fails here

The JSON data is valid but not sure why its still failing.

Answer

einverne picture einverne · Mar 20, 2016

Your JSON string is array. So if you check IsObject() it failed. Take a careful look at the JSON string, you will find that what you care is in [], which show that it is an array.

Take from JSON official site:

An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

Try the following code:

string str_json = "[{\"Node\":\"9478149a08f9\",\"Address\":\"172.17.0.2\",\"ServiceID\":\"HSS\",\"ServiceName\":\"HSS\",\"ServiceTags\":[],\"ServiceAddress\":\"\",\"ServicePort\":6666,\"ServiceEnableTagOverride\":false,\"CreateIndex\":2855,\"ModifyIndex\":2855}]";
rapidjson::Document doc;
doc.Parse(str_json.c_str());

//assert(doc.IsObject());
if(doc.IsArray()){
    cout << "is array" << endl;
}
for(Value::ConstValueIterator itr = doc.Begin(); itr != doc.End(); ++itr){
    const Value& obj = *itr;
    for(Value::ConstMemberIterator it = obj.MemberBegin(); it != obj.MemberEnd(); ++it){
        if(it->value.IsString()){
            cout << it->name.GetString() << ": " << it->value.GetString() << endl;
        }
        // other codes...
    }
}