Extract different set of keys for different nesting level of json

403 Views Asked by At

I have the following JSON object, from which I need to retrieve values of certain keys. For example, in outer JSON object, I need only "timestamp" and "type", next from a nested "meta" object I need only "version", and from nested "payload" I want fields "reason", "type" and "condition" from its nested object "data"

   {
      "timestamp": "1568961295627",
      "type": "test",
      "namespace": "internal",
      "meta": {
        "version": "2.0-test",
        "id": "123"
      },
      "payload": {
        "data": {
        "reason": "user_request",
        "type": "asd",
        "condition": "bad"
        },
        "contentType": "application/json"
      }
    }

I wrote a function to retrieve such data:

void log_values(json_t *data) {
    json_t *obj = NULL;
    json_t *nested = NULL;
    syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(data, "timestamp")));
    syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(data, "type")));
    obj = json_object_get(data, "meta");
    syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(obj, "version")));
    obj = json_object_get(data, "payload");
    nested = json_object_get(obj, "data");
    syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(nested, "reson")));
    syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(nested, "type")));
    syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(nested, "condition")));
}

However, the code looks repetitive and I'm wondering if there is any way to generalize it? The first thing which came to mind is to create a jagged array of pointers to keys needed for each stage, and then walk through the array and retrieve only certain keys on certain nesting level, for example:

char *nested0 = {"timestamp", "type"};
char *nested1 = {"anomaly", "version"};
char *nested2 = {"reason", "type", "condition"};
char *(*keys[])[] = { &nested0, &nested1, &nested2 }

But, this solution does not solve problem regarding where to store key names, which point to nested JSONs (e.g "meta, payload, data").

So, the question is: How to generalize the aforementioned code and what data structure should I use to store names of keys holding a json object and keys for which I need to get values.

1

There are 1 best solutions below

3
On

Take a look at jsmn, it should fit your needs : https://github.com/zserge/jsmn

exemple of what you could do with jsmn :

[user@machine ~]$ ./json_parser_with_keys test.json timestamp type meta/version
timestamp=1568961295627
type=test
meta/version=2.0-test
[user@machine ~]$ ./json_parser_full test.json
/timestamp=1568961295627
/type=test
/namespace=internal
/meta/version=2.0-test
/meta/id=123
/payload/data/reason=user_request
/payload/data/type=asd
/payload/data/condition=bad
/payload/contentType=application/json
[user@machine ~]$