sheredom / json.h

🗄️ single header json parser for C and C++
The Unlicense
698 stars 77 forks source link

Helping Parsing Array Json #78

Closed MasterCna closed 2 years ago

MasterCna commented 2 years ago

Hello, I tried to parse this json format: { "exceptions": [], "category_rules": [{ "rule": { "is_blocked": false }, "name": "porn", "_id": "61cff41a54328f151d2f6a25" }, { "rule": { "is_blocked": false }, "name": "violent", "_id": "61cff41b54328f151d2f6a26" }, { "rule": { "is_blocked": false }, "name": "chat", "_id": "61cff41b54328f151d2f6a27" }, { "rule": { "is_blocked": true }, "name": "gambling", "_id": "61cff41b54328f151d2f6a28" }, { "rule": { "is_blocked": true }, "name": "dating", "_id": "61cff41b54328f151d2f6a29" }, { "rule": { "is_blocked": true }, "name": "game", "_id": "61cff41b54328f151d2f6a2a" }, { "rule": { "is_blocked": true }, "name": "drug", "_id": "61cff41b54328f151d2f6a2b" }] }

Im struggling with parsing these nested array elements. Can anyone help me to parse every single parts of this json ?

MasterCna commented 2 years ago

@sheredom can you help please ?

sheredom commented 2 years ago

Here is how I parsed that (see godbolt for it executing https://godbolt.org/z/vqE1o5jhj)

#include <json.h>
#include <assert.h>
#include <stdio.h>

const char data[] = "{ \"exceptions\": [], \"category_rules\": [{ \"rule\": { \"is_blocked\": false }, \"name\": \"porn\", \"_id\": \"61cff41a54328f151d2f6a25\" }, { \"rule\": { \"is_blocked\": false }, \"name\": \"violent\", \"_id\": \"61cff41b54328f151d2f6a26\" }, { \"rule\": { \"is_blocked\": false }, \"name\": \"chat\", \"_id\": \"61cff41b54328f151d2f6a27\" }, { \"rule\": { \"is_blocked\": true }, \"name\": \"gambling\", \"_id\": \"61cff41b54328f151d2f6a28\" }, { \"rule\": { \"is_blocked\": true }, \"name\": \"dating\", \"_id\": \"61cff41b54328f151d2f6a29\" }, { \"rule\": { \"is_blocked\": true }, \"name\": \"game\", \"_id\": \"61cff41b54328f151d2f6a2a\" }, { \"rule\": { \"is_blocked\": true }, \"name\": \"drug\", \"_id\": \"61cff41b54328f151d2f6a2b\" }] }";

int main() {
    struct json_parse_result_s result;
    struct json_value_s* const root = json_parse_ex(data, sizeof(data) - 1, 0, 0, 0, &result);
    // Use to debug: fprintf(stderr, "%zu %zu %zu %zu\n", result.error, result.error_offset, result.error_line_no, result.error_row_no);
    assert(root);

    struct json_object_s* const root_object = json_value_as_object(root);
    assert(root_object);

    // We've got two things in the root object, exceptions and category_rules.
    assert(root_object->length == 2);

    // We know our object has two fields.
    struct json_array_s* const exceptions = json_value_as_array(root_object->start->value);
    assert(exceptions);
    assert(exceptions->length == 0);

    struct json_array_s* const category_rules = json_value_as_array(root_object->start->next->value);
    assert(category_rules);

    for (struct json_array_element_s* i = category_rules->start; i; i = i->next)
    {
        struct json_object_s* const category = json_value_as_object(i->value);
        assert(category);
        assert(category->length == 3);

        struct json_object_s* const rule = json_value_as_object(category->start->value);
        assert(rule);
        assert(rule->length == 1);

        const int is_blocked = json_value_is_true(rule->start->value);

        struct json_string_s* const name = json_value_as_string(category->start->next->value);
        assert(name);

        struct json_string_s* const _id = json_value_as_string(category->start->next->next->value);
        assert(_id);

        fprintf(stderr, "%s %s %s\n", is_blocked ? "true" : "false", name->string, _id->string);
    }

    return 0;
}