2015-10-01 1 views
2

Я хочу сериализовать вложенную структуру в JSON с помощью Rapidjson, а также хочу иметь возможность сериализовать каждый объект отдельно, поэтому любой класс, который реализует ToJson, может быть сериализован в строку JSON.Rapidjson: добавьте внешний поддоку в документ

В следующем коде 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) и после этого, чтобы CopyFromWheel», соответствующий документ с.

Как это сделать?

ответ

5

Это оказалось более простым, чем я думал. Из GitHub (issue 436):

Самое простое решение, чтобы избежать копирования является повторное использование аллокатора внешнего документа:

rapidjson::Document jsonSubDocument(&jsonDocument.GetAllocator()); 
wheel_.ToJson(jsonSubDocument); 
jsonDocument.AddMember("wheel_", jsonSubDocument, jsonDocument.GetAllocator()); 
Смежные вопросы