Rapidjson:将外部子文档添加到文档
Rapidjson: add external sub-document to document
我想使用 Rapidjson 将嵌套结构序列化为 JSON,我还希望能够分别序列化每个对象,因此任何实现 ToJson
的 class 都可以序列化到 JSON 字符串。
在下面的代码中,Car
有一个 Wheel
成员,并且两个 class 都实现了方法 ToJson
,它用所有内容填充了 rapidjson::Document
他们的成员。此方法从函数模板 ToJsonString
调用,以获取传递对象的格式化 JSON 字符串。
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
template<typename T> std::string ToJsonString(const T &element)
{
rapidjson::StringBuffer jsonBuffer;
rapidjson::PrettyWriter<rapidjson::StringBuffer> jsonWriter(jsonBuffer);
rapidjson::Document jsonDocument;
element.ToJson(jsonDocument);
jsonDocument.Accept(jsonWriter);
return jsonBuffer.GetString();
}
struct Wheel
{
std::string brand_;
int32_t diameter_;
void ToJson(rapidjson::Document &jsonDocument) const
{
jsonDocument.SetObject();
jsonDocument.AddMember("brand_", brand_, jsonDocument.GetAllocator());
jsonDocument.AddMember("diameter_", diameter_, jsonDocument.GetAllocator());
}
};
struct Car
{
std::string brand_;
int64_t mileage_;
Wheel wheel_;
void ToJson(rapidjson::Document &jsonDocument) const
{
jsonDocument.SetObject();
jsonDocument.AddMember("brand_", brand_, jsonDocument.GetAllocator());
jsonDocument.AddMember("mileage_", mileage_, jsonDocument.GetAllocator());
rapidjson::Document jsonSubDocument;
wheel_.ToJson(jsonSubDocument);
jsonDocument.AddMember("wheel_", rapidjson::kNullType, jsonDocument.GetAllocator());
jsonDocument["wheel_"].CopyFrom(jsonSubDocument, jsonDocument.GetAllocator());
}
};
如您所见,Car::ToJson
调用 Wheel::ToJson
以获取 Wheel
的描述并将其添加为子对象,但我想不到由于分配管理,这是一个可接受的解决方案(我也阅读了其他问题)。
我找到的解决方法是在 Car
的 jsonDocument
中添加一个具有随机字段值的成员(在本例中为 rapidjson::kNullType
),然后添加到 CopyFrom
Wheel
对应的文件。
我该怎么做?
事实证明这比我想象的要简单。来自 GitHub (issue 436):
The easiest solution to avoid the copy is to reuse the allocator of the outer document:
rapidjson::Document jsonSubDocument(&jsonDocument.GetAllocator());
wheel_.ToJson(jsonSubDocument);
jsonDocument.AddMember("wheel_", jsonSubDocument, jsonDocument.GetAllocator());
我想使用 Rapidjson 将嵌套结构序列化为 JSON,我还希望能够分别序列化每个对象,因此任何实现 ToJson
的 class 都可以序列化到 JSON 字符串。
在下面的代码中,Car
有一个 Wheel
成员,并且两个 class 都实现了方法 ToJson
,它用所有内容填充了 rapidjson::Document
他们的成员。此方法从函数模板 ToJsonString
调用,以获取传递对象的格式化 JSON 字符串。
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
template<typename T> std::string ToJsonString(const T &element)
{
rapidjson::StringBuffer jsonBuffer;
rapidjson::PrettyWriter<rapidjson::StringBuffer> jsonWriter(jsonBuffer);
rapidjson::Document jsonDocument;
element.ToJson(jsonDocument);
jsonDocument.Accept(jsonWriter);
return jsonBuffer.GetString();
}
struct Wheel
{
std::string brand_;
int32_t diameter_;
void ToJson(rapidjson::Document &jsonDocument) const
{
jsonDocument.SetObject();
jsonDocument.AddMember("brand_", brand_, jsonDocument.GetAllocator());
jsonDocument.AddMember("diameter_", diameter_, jsonDocument.GetAllocator());
}
};
struct Car
{
std::string brand_;
int64_t mileage_;
Wheel wheel_;
void ToJson(rapidjson::Document &jsonDocument) const
{
jsonDocument.SetObject();
jsonDocument.AddMember("brand_", brand_, jsonDocument.GetAllocator());
jsonDocument.AddMember("mileage_", mileage_, jsonDocument.GetAllocator());
rapidjson::Document jsonSubDocument;
wheel_.ToJson(jsonSubDocument);
jsonDocument.AddMember("wheel_", rapidjson::kNullType, jsonDocument.GetAllocator());
jsonDocument["wheel_"].CopyFrom(jsonSubDocument, jsonDocument.GetAllocator());
}
};
如您所见,Car::ToJson
调用 Wheel::ToJson
以获取 Wheel
的描述并将其添加为子对象,但我想不到由于分配管理,这是一个可接受的解决方案(我也阅读了其他问题)。
我找到的解决方法是在 Car
的 jsonDocument
中添加一个具有随机字段值的成员(在本例中为 rapidjson::kNullType
),然后添加到 CopyFrom
Wheel
对应的文件。
我该怎么做?
事实证明这比我想象的要简单。来自 GitHub (issue 436):
The easiest solution to avoid the copy is to reuse the allocator of the outer document:
rapidjson::Document jsonSubDocument(&jsonDocument.GetAllocator()); wheel_.ToJson(jsonSubDocument); jsonDocument.AddMember("wheel_", jsonSubDocument, jsonDocument.GetAllocator());