Rapidjson:将外部子文档添加到文档中

时间:2015-10-01 20:54:39

标签: c++ json rapidjson

我想使用Rapidjson将嵌套结构序列化为JSON,我也希望能够单独序列化每个对象,因此任何实现ToJson的类都可以序列化为JSON字符串。

在以下代码中,Car有一个Wheel成员,并且这两个类都实现了方法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),之后为{ {1}} CopyFrom的相应文档。

我该怎么做?

1 个答案:

答案 0 :(得分:6)

事实证明这比我想象的要简单得多。来自GitHub(issue 436):

  

避免复制的最简单方法是重用外部文档的分配器:

rapidjson::Document jsonSubDocument(&jsonDocument.GetAllocator());
wheel_.ToJson(jsonSubDocument);
jsonDocument.AddMember("wheel_", jsonSubDocument, jsonDocument.GetAllocator());