Tencent / rapidjson

A fast JSON parser/generator for C++ with both SAX/DOM style API
http://rapidjson.org/
Other
14.26k stars 3.53k forks source link

Compiler error while retrieving an json array and copying it to document #1187

Open ArunJaganath opened 6 years ago

ArunJaganath commented 6 years ago

Hi, I am parsing JSON a file while contains the details of a directory. This file contains an array within which there are many objects and these objects may contain other objects or array.

The following is the code snippet. case rapidjson::kObjectType: fprintf(stderr, "Object \n");

                for (rapidjson::Value::ConstMemberIterator itr = itr3->MemberBegin();
                        itr != itr3->MemberEnd(); ++itr)
                {
                    printf("Type of member %s is %s\n",
                            itr->name.GetString(), kt[itr->value.GetType()]);

                    if (itr->value.GetType() == rapidjson::kArrayType)
                    {
                        printf("Name : %s= \n", itr->name.GetString());

                        //rapidjson::Value& temp_val =

                        //rapidjson::Document doc = (*itr).value;
                        rapidjson::Value& temp_val = itr->value.GetArray();

                        rapidjson::Document  temp_doc;

                        temp_doc.CopyFrom(temp_val, temp_doc.GetAllocator());
                           }

The compiler error is as follows... src/TestApplication.cpp: In member function ‘bool TestApplication::process_diff_json_array(rapidjson::Document&, rapidjson::Document&)’: src/TestApplication.cpp:974:60: error: invalid initialization of non-const reference of type ‘rapidjson::Value& {aka rapidjson::GenericValue<rapidjson::UTF8<> >&}’ from an rvalue of type ‘rapidjson::GenericValue<rapidjson::UTF8<> >::ConstArray {aka rapidjson::GenericArray<true, rapidjson::GenericValue<rapidjson::UTF8<> > >}’ rapidjson::Value& temp_val = itr->value.GetArray();

Any help would be really appreciated.

miloyip commented 6 years ago

Don't need GetArray().

rapidjson::Value& temp_val = itr->value;
pah commented 6 years ago

Additionally, you might need to make it a const reference. But then again, you can simplify it to:

    printf("Name : %s= \n", itr->name.GetString());
    rapidjson::Document  temp_doc;
    temp_doc.CopyFrom(itr->value, temp_doc.GetAllocator());
ArunJaganath commented 6 years ago

Thanks miloyip and pah, I have this requirement to get the entire object in to sub document, but what is see is only the value being in it and not the key. due to which I get a runtime error(which is in the end of this post). This is due to the rapidjson::Value::ConstMemberIterator that i am using in my recursive call. Any idea how i can get this entire member object? The following is my code snippet for recursive function call.

bool process_json_array( rapidjson::Document& src_doc)
{
    bool status=true;

    rapidjson::StringBuffer tsrc_buf;
    rapidjson::Writer<rapidjson::StringBuffer> writer(tsrc_buf);
    src_doc.Accept(writer);

    DLOG_DEBUG( "SRC Doc Output: %s ", tsrc_buf.GetString());

    for (rapidjson::Value::ConstMemberIterator itr2 = src_doc.MemberBegin(); itr2 != src_doc.MemberEnd(); ++itr2)
    {

        if (itr2->value.GetType() == rapidjson::kArrayType)
        {
            for (rapidjson::Value::ConstValueIterator itr3 = itr2->value.Begin(); itr3 != itr2->value.End(); ++itr3)
            {
                switch (itr3->GetType())
                {
                    case rapidjson::kObjectType:

                    for (rapidjson::Value::ConstMemberIterator itr = itr3->MemberBegin();
                            itr != itr3->MemberEnd(); ++itr)
                    {
                        printf("Type of member %s is %s\n",
                                itr->name.GetString(), kt[itr->value.GetType()]);

                        if (itr->value.GetType() == rapidjson::kArrayType)
                        {
                            printf("Name : %s= \n", itr->name.GetString());

                            rapidjson::Document doc;

                            doc.CopyFrom(itr->value, doc.GetAllocator());
                            process_json_array(doc);
                        }
                    }
                    break;

                default: printf("???\n"); break;
                }
            }
        }
    }
    return status;
}
rapidjson::GenericValue<Encoding, Allocator>::MemberIterator rapidjson::GenericValue<Encoding, Allocator>::MemberBegin() [with Encoding = rapidjson::UTF8<>; Allocator = rapidjson::MemoryPoolAllocator<>; rapidjson::GenericValue<Encoding, Allocator>::MemberIterator = rapidjson::GenericMemberIterator<false, rapidjson::UTF8<>, rapidjson::MemoryPoolAllocator<> >]: Assertion `IsObject()' failed.
miloyip commented 6 years ago

When you recursively call process_json_array(doc), that doc is copied from itr->value, which is an array. So that doc is an array. Then when running process_json_array(src_doc), src_doc.MemberBegin() must fail because src_doc is an array.

ArunJaganath commented 6 years ago

Hi Milo,

I have a format something like this.. "Child": [{ "name": "TestApplication.h", "path": "test_json_writer/inc", "type": "file", "size": 4386, "timestamp": 1519022379, "etag": "30080725cb594ed3cbaa75b4102406dadf3f558600aaee0bad91e724bdd34aef" }]

What i have in the itr->value is [{ "name": "TestApplication.h", "path": "test_json_writer/inc", "type": "file", "size": 4386, "timestamp": 1519022379, "etag": "30080725cb594ed3cbaa75b4102406dadf3f558600aaee0bad91e724bdd34aef" }]

I would like to have some thing like this.....

{ "Child": [{ "name": "TestApplication.h", "path": "test_json_writer/inc", "type": "file", "size": 4386, "timestamp": 1519022379, "etag": "30080725cb594ed3cbaa75b4102406dadf3f558600aaee0bad91e724bdd34aef" }] } In order to acheive this i did try... rapidjson::Value t_object(rapidjson::kObjectType); t_object.CopyFrom(itr->value, doc.GetAllocator()); rapidjson::Value dir_name_key(itr->name.GetString(), doc.GetAllocator()); doc.AddMember(dir_name_key, t_object, doc.GetAllocator()); but it's still an array

Your help is highly appreciated....

Bishalsahoo commented 6 years ago

This is the exact problem that I am looking for to be solved while using recursion , any help to solve this problem will be greatly appreciated as I am unable to find the way or any related example to get the idea