json-c:从子数组访问值的最简单方法

时间:2017-02-18 01:27:31

标签: c json-c

{
    "name":"John Doe",
    "dob":"2005-01-03",
    "scores":
    {
        "math":
        {
            "lowest":65,
            "highest":98
        },
        "english":
        {
            "lowest":75,
            "highest":80
        },
        "history":
        {
            "lowest":50,
            "highest":85
        }
    }
}

使用json-c访问上述JSON对象中最高数学分数的最简单方法是什么?

是否可以使用与 json_object_object_get类似的东西(jsonobj," scores.math.highest")

如果没有,我是否必须检索每个单独的数组以获得最高分?即。获得分数,然后获得数学并最终获得最高分?

谢谢!

1 个答案:

答案 0 :(得分:1)

查看JSON-C docs它似乎没有一种简单的方法可以深入到结构中。你必须自己做。像这样:

struct json_object *json_object_get_with_keys(
    struct json_object *obj,
    const char *keys[]
) {
    while( keys[0] != NULL ) {
        if( !json_object_object_get_ex(obj, keys[0], &obj) ) {
            fprintf(stderr, "Can't find key %s\n", keys[0]);
            return NULL;
        }

        keys++;
    }

    return obj;
}

传递一个空终止的键数组,它将向下钻取(或返回null)。

const char *keys[] = {"scores", "math", "highest", NULL};
struct json_object *obj = json_object_get_with_keys(top, keys);
if( obj != NULL ) {
    printf("%s\n", json_object_to_json_string(obj));
}

相反,请使用JSON-Glib。它有JSONPath更熟悉,您可以使用$.scores.english.highest

JsonNode *result_node = json_path_query(
    "$.scores.english.highest",
    json_parser_get_root(parser),
    &error
);
if( error != NULL ) {
    fprintf(stderr, "%s", error->message);
    exit(1);
}

/* It returns a node containing an array. Why doesn't it just return an array? */
JsonArray *results = json_node_get_array(result_node);
if( json_array_get_length( results ) == 1 ) {
    printf("highest: %ld\n", json_array_get_int_element(results, 0));
}
else {
    fprintf(stderr, "Couldn't find it\n");
}

使用起来有点尴尬,但是你可以通过一些包装函数来处理脚手架和错误处理。