Rapidjson: добавление внешнего вложенного документа в документ
Я хочу сериализовать вложенную структуру в JSON с помощью Rapidjson, а также я хочу иметь возможность сериализовать каждый объект отдельно, поэтому любой класс, реализующий 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 S jsonDocument со случайным значением поля (в данном случае rapidjson::kNullType), а затем в CopyFrom соответствующий документ Wheel.
Как я могу это сделать?
1 ответ:
Это оказалось гораздо проще, чем я думал. Из GitHub (выпуск 436):
Самое простое решение избежать копирования-повторно использовать распределитель внешнего документа:
rapidjson::Document jsonSubDocument(&jsonDocument.GetAllocator()); wheel_.ToJson(jsonSubDocument); jsonDocument.AddMember("wheel_", jsonSubDocument, jsonDocument.GetAllocator());
Comments