Как установить разные десятичные разряды в одном и том же документе rapidjson

Я сделал документ Rapidjson со всеми своими объектами и значениями, используя обычный метод AddMember(). Теперь я хочу получить строку из этого документа для публикации брокеру mqtt. Но внутри этой строки некоторые члены должны иметь 2 десятичных знака, некоторые только один, а другие все десятичные знаки. Я не нахожу, как установить десятичный разряд для определенного члена после того, как документ был полностью построен.

Мне удалось сделать это, создав документ json с помощью средства записи, но это не то, что я хочу сделать, потому что этот документ нельзя легко изменить:

#include <string>
#include <iostream>
#include <sstream>
#include <rapidjson/document.h>     // rapidjson's DOM-style API
#include <rapidjson/prettywriter.h> // for stringify JSON
#include <rapidjson/stringbuffer.h>

using namespace rapidjson;
using namespace std;

int main (int argc, char* argv[])
{
    Document doc;
    StringBuffer buffer;
    Writer<StringBuffer> writer(buffer);
    writer.StartObject();
    writer.Key("member1");
    writer.SetMaxDecimalPlaces(2);
    writer.Double(1.0000001);
    writer.Key("member2");
    writer.SetMaxDecimalPlaces(3);
    writer.Double(3.123456);
    writer.Key("member3");
    writer.SetMaxDecimalPlaces(8);
    writer.Double(2.123456);
    writer.EndObject();
    cout << buffer.GetString() << endl;
    return 0;
}
./decimal
{"member1":1.0,"member2":3.123,"member3":2.123456}

Теперь, как я создаю свой документ:

#include <string>
#include <iostream>
#include <sstream>
#include <rapidjson/document.h>     // rapidjson's DOM-style API
#include <rapidjson/prettywriter.h> // for stringify JSON
#include <rapidjson/stringbuffer.h>

using namespace rapidjson;
using namespace std;

int main (int argc, char* argv[])
{
    Document doc;
    Document::AllocatorType& allocator = doc.GetAllocator();
    StringBuffer buffer;
    Writer<StringBuffer> writer(buffer);
    doc.SetObject();
    doc.AddMember("member1", 1.0000001, allocator);
    doc.AddMember("member3", 3.123456, allocator);
    doc.AddMember("member2", 2.123456, allocator);
    writer.SetMaxDecimalPlaces(2);
    doc.Accept(writer);

    cout << buffer.GetString() << endl;
    return 0;
}
./decimal
{"member1":1.0,"member2":2.12,"member3":3.12}

Таким образом, SetMaxDecimalPlaces() применяется ко всему документу.

Я хотел бы получить тот же вывод, что и первый пример кода, но с использованием документа, созданного из второго исходного кода. Как я могу указать писателю форматировать каждый элемент по-разному?


person Kurt4u    schedule 17.05.2019    source источник


Ответы (1)


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

StringBuffer buffer;

Writer<StringBuffer> writer1(buffer); // original writer
Writer<StringBuffer> writer2(buffer); // a new second writer

writer1.SetMaxDecimalPlaces(1);
writer2.SetMaxDecimalPlaces(2);

а затем используйте специальные писатели для записи непосредственно в буфер вместо использования документа для вызова писателя:

writer.Key("member1");
writer.Double(1.0);

writer2.Key("member2");
writer2.Double(2.12);

writer2.Key("member3");
writer2.Double(3.12);

Полный пример:

using namespace rapidjson;
using namespace std;

int main (int argc, char* argv[])
{
    StringBuffer buffer;

    Writer<StringBuffer> writer1(buffer);
    Writer<StringBuffer> writer2(buffer);

    writer1.SetMaxDecimalPlaces(2);
    writer2.SetMaxDecimalPlaces(2);

    writer1.StartObject();

    writer1.Key("member1");
    writer1.Double(1.0);

    writer2.Key("member2");
    writer2.Double(2.12);

    writer2.Key("member3");
    writer2.Double(3.12);

    writer1.EndObject();

    cout << buffer.GetString() << endl;
    return 0;
}
person John Phu Nguyen    schedule 14.04.2020