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;
}

What's the error about this demo ?
Thank you !
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());
Most helpful comment
It is because the
tempDocand the values allocated during parsing is destroyed at the end ofAddData().A simple fix is: