Rapidjson: [Help] I am confused about how to PushBack an object into an existed array.

Created on 8 Apr 2016  路  3Comments  路  Source: Tencent/rapidjson

I have a json just like this: {"version":1.0, "data": {"count": 0, "datalist": []}} . Then I'd like to add some data into the "datalist" array dynamically, but I can't find a real way to do that.
There is a demo I hava writen.

data_json.h:

#ifndef DATA_JSON_H
#define DATA_JSON_H

#include <string>

#include "rapidjson/document.h"

using namespace std;

class DataJson 
{
public:
    DataJson(void);
    ~DataJson(void);

    void CreateJson();
    void AddData(const string & proJson); 
    void GetString(string & str);

private:
    rapidjson::Document     m_document;
};

#endif // DATA_JSON_H

data_json.cpp:

#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"

#include "data_json.h"

DataJson::DataJson(void)
{
}


DataJson::~DataJson(void)
{
}

void DataJson::CreateJson()
{
    m_document.Parse("{\"version\":1.0, \"data\": {\"count\": 0, \"datalist\": []}}");
}

void DataJson::AddData(const string & json)
{
    rapidjson::Document tempDoc;
    tempDoc.Parse(json.c_str());
    if(! tempDoc.IsObject())
    {
        return;
    }
    rapidjson::Document::AllocatorType &allocator = m_document.GetAllocator();
    if(m_document.HasMember("data"))
    {
        rapidjson::Value &dataObject = m_document["data"];
        if(dataObject.IsObject())
        {
            bool addNewData = false;
            if(dataObject.HasMember("datalist"))
            {
                rapidjson::Value &dataList = dataObject["datalist"];
                if(dataList.IsArray())
                {
                    dataList.PushBack(tempDoc.GetObject(), allocator);
                    addNewData = true;
                }
            }
            else
            {
                rapidjson::Value dataArray(rapidjson::kArrayType);
                dataArray.PushBack(tempDoc.GetObject(), allocator);
                dataObject.AddMember("datalist", dataArray, allocator);
                addNewData = true;
            }

            if(addNewData)
            {
                rapidjson::Value::MemberIterator countItr = dataObject.FindMember("count");
                if(countItr != dataObject.MemberEnd())
                {
                    if(countItr->value.IsInt())
                    {
                        countItr->value.SetInt(countItr->value.GetInt() + 1);
                    }
                }
                else
                {
                    rapidjson::Value dataCount(rapidjson::kNumberType);
                    dataCount.SetInt(1);
                    dataObject.AddMember("count", dataCount, allocator);
                }
            }
        }
    }
}

void DataJson::GetString(string & str)
{
    str.clear();
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    m_document.Accept(writer);
    str.append(buffer.GetString());
}

main.cpp:

#include <string>
#include <iostream>
#include "data_json.h"

using namespace std;

int main()
{
    DataJson dataJson;
    dataJson.CreateJson();

    string jsonStr;
    string dataStr;

    dataJson.GetString(jsonStr);
    cout << "Json:" << jsonStr << endl;

    cout << "please input the data json: " <<endl;
    cin >> dataStr;
    while(dataStr != "0")
    {
        dataJson.AddData(dataStr);
        dataJson.GetString(jsonStr);
        cout << "Json:" << jsonStr << endl;

        cout << "please input the data json: " <<endl;
        cin >> dataStr;
    }
    return 0;
}

1b64 tm

What's the error about this demo ?

Thank you !

Most helpful comment

It is because the tempDoc and the values allocated during parsing is destroyed at the end of AddData().

A simple fix is:

rapidjson::Document tempDoc(*m_document.GetAllocator());

All 3 comments

It is because the tempDoc and the values allocated during parsing is destroyed at the end of AddData().

A simple fix is:

rapidjson::Document tempDoc(*m_document.GetAllocator());

Do you mean that for tempDoc, you need to use an allocator based off m_document? The above doesn't compile. There isn't a constructor for rapidjson::Document that takes *m_document.GetAllocator()

Then again, that's what this person was doing in the first place....using allocator based off m_document with tempDoc.

rapidjson::Document tempDoc(*m_document.GetAllocator()); Here I think
it is more

rapidjson::Document tempDoc(&m_document.GetAllocator());
Was this page helpful?
0 / 5 - 0 ratings

Related issues

leeyiw picture leeyiw  路  4Comments

accelerated picture accelerated  路  6Comments

vzaluckis picture vzaluckis  路  4Comments

oneonce picture oneonce  路  3Comments

jimmyorourke picture jimmyorourke  路  3Comments