// JSON to JSONx conversion example, using SAX API. // JSONx is an IBM standard format to represent JSON as XML. // https://www-01.ibm.com/support/knowledgecenter/SS9H2Y_7.1.0/com.ibm.dp.doc/json_jsonx.html // This example parses JSON text from stdin with validation, // and convert to JSONx format to stdout. // Need compile with -D__STDC_FORMAT_MACROS for defining PRId64 and PRIu64 macros. #include "rapidjson/reader.h" #include "rapidjson/stringbuffer.h" #include "rapidjson/filereadstream.h" #include "rapidjson/filewritestream.h" #include "rapidjson/error/en.h" #include using namespace rapidjson; // For simplicity, this example only read/write in UTF-8 encoding template class JsonxWriter { public: JsonxWriter(OutputStream& os) : os_(os), name_(), level_(0), hasName_(false) { } bool Null() { return WriteStartElement("null", true); } bool Bool(bool b) { return WriteStartElement("boolean") && WriteString(b ? "true" : "false") && WriteEndElement("boolean"); } bool Int(int i) { char buffer[12]; return WriteNumberElement(buffer, sprintf(buffer, "%d", i)); } bool Uint(unsigned i) { char buffer[11]; return WriteNumberElement(buffer, sprintf(buffer, "%u", i)); } bool Int64(int64_t i) { char buffer[21]; return WriteNumberElement(buffer, sprintf(buffer, "%" PRId64, i)); } bool Uint64(uint64_t i) { char buffer[21]; return WriteNumberElement(buffer, sprintf(buffer, "%" PRIu64, i)); } bool Double(double d) { char buffer[30]; return WriteNumberElement(buffer, sprintf(buffer, "%.17g", d)); } bool RawNumber(const char* str, SizeType length, bool) { return WriteStartElement("number") && WriteEscapedText(str, length) && WriteEndElement("number"); } bool String(const char* str, SizeType length, bool) { return WriteStartElement("string") && WriteEscapedText(str, length) && WriteEndElement("string"); } bool StartObject() { return WriteStartElement("object"); } bool Key(const char* str, SizeType length, bool) { // backup key to name_ name_.Clear(); for (SizeType i = 0; i < length; i++) name_.Put(str[i]); hasName_ = true; return true; } bool EndObject(SizeType) { return WriteEndElement("object"); } bool StartArray() { return WriteStartElement("array"); } bool EndArray(SizeType) { return WriteEndElement("array"); } private: bool WriteString(const char* s) { while (*s) os_.Put(*s++); return true; } bool WriteEscapedAttributeValue(const char* s, size_t length) { for (size_t i = 0; i < length; i++) { switch (s[i]) { case '&': WriteString("&"); break; case '<': WriteString("<"); break; case '"': WriteString("""); break; default: os_.Put(s[i]); break; } } return true; } bool WriteEscapedText(const char* s, size_t length) { for (size_t i = 0; i < length; i++) { switch (s[i]) { case '&': WriteString("&"); break; case '<': WriteString("<"); break; default: os_.Put(s[i]); break; } } return true; } bool WriteStartElement(const char* type, bool emptyElement = false) { if (level_ == 0) if (!WriteString("")) return false; if (!WriteString(""); else { level_++; return WriteString(">"); } } bool WriteEndElement(const char* type) { if (!WriteString("")) return false; // For the last end tag, flush the output stream. if (--level_ == 0) os_.Flush(); return true; } bool WriteNumberElement(const char* buffer, int length) { if (!WriteStartElement("number")) return false; for (int j = 0; j < length; j++) os_.Put(buffer[j]); return WriteEndElement("number"); } OutputStream& os_; StringBuffer name_; unsigned level_; bool hasName_; }; int main(int, char*[]) { // Prepare JSON reader and input stream. Reader reader; char readBuffer[65536]; FileReadStream is(stdin, readBuffer, sizeof(readBuffer)); // Prepare JSON writer and output stream. char writeBuffer[65536]; FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer)); JsonxWriter writer(os); // JSON reader parse from the input stream and let writer generate the output. if (!reader.Parse(is, writer)) { fprintf(stderr, "\nError(%u): %s\n", static_cast(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode())); return 1; } return 0; }