سؤال

I am trying to get the array from my JSON Stinrg defined in the main function. I have used libjson API for this, simple key value is easy to get so I am able to get the value of RootA but how about this array in ChildA. Please let me know

#include <iostream>
#include <libjson/libjson.h>
#include <stdio.h>
#include <string.h>

using namespace std;

char rootA[20];
int childB;
int *childInt;

void ParseJSON(JSONNODE *n) {
    if (n == NULL) {
        printf("Invalid JSON Node\n");
        return;
    }

    JSONNODE_ITERATOR i = json_begin(n);
    while (i != json_end(n)) {
        if (*i == NULL) {
            printf("Invalid JSON Node\n");
            return;
        }

        // recursively call ourselves to dig deeper into the tree
        if (json_type(*i) == JSON_ARRAY || json_type(*i) == JSON_NODE) {
            ParseJSON(*i);
        }

        // get the node name and value as a string
        json_char *node_name = json_name(*i);

        // find out where to store the values
        if (strcmp(node_name, "RootA") == 0) {
            json_char *node_value = json_as_string(*i);
            strcpy(rootA, node_value);
            cout << rootA<<"\n";
            json_free(node_value);
        } else if (strcmp(node_name, "ChildA") == 0) {
            JSONNODE *node_value = json_as_array(*i);

            childInt=reinterpret_cast<int *>(&node_value);
            cout << childInt[0]<<"\n";
            cout << childInt[1]<<"\n";
            json_free(node_value);
        } else if (strcmp(node_name, "ChildB") == 0) {
            childB = json_as_int(*i);
            cout << childB;
        }
        // cleanup and increment the iterator
        json_free(node_name);
        ++i;
    }
}

int main(int argc, char **argv) {
    char
            *json =
                    "{\"RootA\":\"Value in parent node\",\"ChildNode\":{\"ChildA\":[1,2],\"ChildB\":42}}";
    JSONNODE *n = json_parse(json);
    ParseJSON(n);
    json_delete(n);
    return 0;
}
هل كانت مفيدة؟

المحلول

Thanks not-sehe but I got the solution for this

Ok I got it... treat array as a node and iterate over it again as if its a value with blank key. You can see the code part which did it..

if (json_type(*i) == JSON_ARRAY) {
    cout << "\n Its a Json Array";
    JSONNODE *arrayValue = json_as_array(*i);
    JSONNODE_ITERATOR i1 = json_begin(arrayValue);
    while (i1 != json_end(arrayValue)) {
            cout << "\n In Array Loop ";
        cout << json_as_int(*i1);
        ++i1;
    }
}

نصائح أخرى

This is probably not the answer you were looking for, but let me just demonstrate that a library with a slightly more modern interface makes this a lot easier (test.cpp):

#include <sstream>
#include "JSON.hpp"

int main()
{
    auto document = JSON::readFrom(std::istringstream(
                "{\"RootA\":\"Value in parent node\",\"ChildNode\":{\"ChildA\":[1,2],\"ChildB\":42}}"));

    auto childA = as_object(
                as_object(document)[L"ChildNode"]
            )[L"ChildA"];

    std::cout << childA << std::endl;
}

Which prints

[1,2]

It's using my own minimalist implementation of the rfc4627 specs. It's minimalist in interface only, supporting the full syntax and UNICODE.

The API interface is quite limited, but you can already see that working without C-style pointers, with proper dictionary lookups, key comparisons etc. makes it a less tedious and error prone:

// or use each value
for(auto& value : as_array(childA).values)
    std::cout << value << std::endl;

// more advanced:
JSON::Value expected = JSON::Object {
    { L"RootA", L"Value in parent node" },
    { L"ChildNode", JSON::Object {
             { L"ChildA", JSON::Array { 1,2 } },
             { L"ChildB", 42 },
         } },
};
std::cout << "Check equality: " << std::boolalpha << (document == expected) << std::endl;
std::cout << "Serialized: " << document;

See the full parser implementation (note: it includes serialization too) at github: https://github.com/sehe/spirit-v2-json/tree/q17064905

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top