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 的描述并将其添加为子对象,但我想不到由于分配管理,这是一个可接受的解决方案(我也阅读了其他问题)。

我找到的解决方法是在 CarjsonDocument 中添加一个具有随机字段值的成员(在本例中为 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());