20

How to serialize RapidJSON document to a string?
In all the examples the serializing text is redirected to the standard output through the FileStream, but I need to redirect it to a string variable.

Lochana Thenuwara
  • 415
  • 2
  • 4
  • 12

4 Answers4

19

In the first page of the project, the code already shows how to serialize a document into a string (stringify a document):

// 3. Stringify the DOM
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
d.Accept(writer);

// Output {"project":"rapidjson","stars":11}
std::cout << buffer.GetString() << std::endl;

buffer.GetString() here returns a string of const char* type. It also has a buffer.GetSize() for returning the size of output string. So, if you would convert it to a std::string, the best way is:

std::string s(buffer.GetString(), buffer.GetSize());

The tutorial.cpp also show the same thing, in addition to other common usage of RapidJSON.

Milo Yip
  • 4,902
  • 2
  • 25
  • 27
  • 7
    Will the destructor of `buffer` free the `buffer.GetString()` ? If yes, then is there a way to *move* the content of `buffer` rather than *copy* it? – Vahagn Jan 31 '17 at 08:54
18

Like this:

const char *GetJsonText()
{
  rapidjson::StringBuffer buffer;

  buffer.Clear();

  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  doc.Accept(writer);

  return strdup( buffer.GetString() );
}

Then of couse you have to call free() on the return, or do:

return string( buffer.GetString() );

instead.

A.Franzen
  • 725
  • 4
  • 10
  • Thanks... but the line "doc.Accept(writer);" it returns "null" value. I don't understand the reason.????? when I do "doc['x'].Accept(writer);" It returns the value of x. why the null value....? :( – Lochana Thenuwara Oct 28 '15 at 07:13
  • You will have to post some example code, I can't tell you by just guessing. – A.Franzen Oct 29 '15 at 13:33
  • I just had a quick look. Accept returns a bool. It can't return NULL. I consider doc to be of type rapidjson::Document, initialized with doc.Parse( jsonDaten.c_str() );. – A.Franzen Oct 29 '15 at 14:44
  • Does this work for nested rapidjson documents as well? – Bharath Nov 16 '20 at 18:40
  • I have a question, may be a stupid question, what is the object type of `buffer.GetString()` – naman1994 Oct 21 '21 at 04:44
4

Example code:

Document document;
const char *json = " { \"x\" : \"0.01\", \"y\" :\"0.02\" , \"z\" : \"0.03\"} ";

document.Parse<0>(json);

//convert document to string

StringBuffer strbuf;
strbuf.Clear();

Writer<StringBuffer> writer(strbuf);
document.Accept(writer);

std::string ownShipRadarString = strbuf.GetString();
std::cout << "**********************************************" << ownShipRadarString << std::endl;
Lochana Thenuwara
  • 415
  • 2
  • 4
  • 12
2

To avoid having to copy out the string contents, you can create a rapidjson Stream-concept class to wrap an existing std::string, ref: https://github.com/Tencent/rapidjson/issues/846#issuecomment-298088278

In fact, not all the methods implemented there are required. This should do:

void writeDocumentToString(const rapidjson::Document& document,
                           std::string& output)
{
  class StringHolder
  {
  public:
    typedef char Ch;
    StringHolder(std::string& s) : s_(s) { s_.reserve(4096); }
    void Put(char c) { s_.push_back(c); }
    void Flush() { return; }

  private:
    std::string& s_;
  };

  StringHolder os(output);
  rapidjson::Writer<StringHolder> writer(os);
  document.Accept(writer);
}
Simon Pickup
  • 832
  • 12
  • 19