hagope
hagope

Reputation: 5531

Parsing deeply nested JSON key using json-c

I'm using the json-c library, and after reviewing the documentation, I couldn't find a way to get at a deeply nested key/value without using a bunch of loops, here's what I've tried:

json_object_object_foreach(json_data_obj, key, val) {
  printf("KEY:%s\t VAL:%s\n", key, json_object_to_json_string(val));
  /* TODO: Traverse the JSON
   * "results" => "channel" => "item" => "condition" => "temp"
   */
}

Here's the output:

KEY:query        VAL:{ "count": 1, "created": "2015-04-10T06:05:12Z", "lang": "en-US", "results": { "channel": { "item": { "condition": { "code": "33", "date": "Thu, 09 Apr 2015 9:55 pm PDT", "temp": "56", "text": "Fair" } } } } }

How can I get the temp value without using json_object_object_foreach() macro several times?

Upvotes: 2

Views: 3991

Answers (2)

Simone
Simone

Reputation: 85

Meanwhile (since json-c 0.13) one can reach deeply nested object by walking the object tree with the json_c_visit function.

int json_c_visit (
    json_object * jso,
    int future_flags,
    json_c_visit_userfunc * userfunc,
    void * userarg 
)   

The function walks to every object of the json document and calls the user defined function userfunc. One can also steere the traveling through the tree with returnvalues of the userfunc. Take the unittests and the expected output as examples how to use the function.

Upvotes: 3

cigarman
cigarman

Reputation: 651

You'll likely have to call json_object_object_get_ex for each object until you get to the key/value pair that you want, checking for the existence of each key along the way.

There may be another way, but this is what I've had to do on a recent project working equally complex JSON data.

The following code assumes b contains your JSON string.

json_object *json_obj, *results_obj, *channel_obj, *item_obj, *condition_obj,*temp_obj;
int exists;
char *temperature_string;

json_obj = json_tokener_parse(b); 
exists=json_object_object_get_ex(json_obj,"results",&results_obj);
if(exists==false) { 
  printf("\"results\" not found in JSON"); 
  return; 
} 
exists=json_object_object_get_ex(results_obj,"channel",&channel_obj); 
if(exists==false) { 
  printf("key \"channel\" not found in JSON"); 
  return; 
} 
exists=json_object_object_get_ex(channel_obj,"item",&item_obj); 
if(exists==false) { 
  printf("key \"item\" not found in JSON"); 
  return; 
}
exists=json_object_object_get_ex(item_obj,"condition",&condition_obj); 
if(exists==false) { 
  printf("key \"condition\" not found in JSON"); 
  return; 
}
exists=json_object_object_get_ex(condition_obj,"temp",&temp_obj); 
if(exists==false) { 
   printf("key \"temp\" not found in JSON"); 
   return; 
}
temperature_string = json_object_get_string(temp_obj); //temperature_string now contains "56"

Upvotes: 1

Related Questions