diff options
author | Milo Yip <miloyip@gmail.com> | 2016-02-08 19:09:39 +0300 |
---|---|---|
committer | Milo Yip <miloyip@gmail.com> | 2016-02-08 19:09:39 +0300 |
commit | 9f1dcef6b1645a3c3bf34a2c0a85f75e3b3e61dd (patch) | |
tree | d2433c8756f6d9b0635a35303341048c22978c24 | |
parent | c828037784278037422198f4d0c8cac4399e2c59 (diff) |
Add jsonx example
-rw-r--r-- | example/CMakeLists.txt | 1 | ||||
-rw-r--r-- | example/jsonx/jsonx.cpp | 199 |
2 files changed, 200 insertions, 0 deletions
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index cfb55ddc..f4829cc8 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -6,6 +6,7 @@ cmake_minimum_required(VERSION 2.8) set(EXAMPLES capitalize condense + jsonx messagereader pretty prettyauto diff --git a/example/jsonx/jsonx.cpp b/example/jsonx/jsonx.cpp new file mode 100644 index 00000000..b6f30102 --- /dev/null +++ b/example/jsonx/jsonx.cpp @@ -0,0 +1,199 @@ +// JSON to JSONx conversion exmaple, 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. + +#include "rapidjson/reader.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/filereadstream.h" +#include "rapidjson/filewritestream.h" +#include "rapidjson/error/en.h" +#include <cstdio> + +using namespace rapidjson; + +// For simplicity, this example only read/write in UTF-8 encoding +template <typename OutputStream> +class JsonxWriter { +public: + JsonxWriter(OutputStream& os) : os_(os), 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 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("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")) + return false; + + if (!WriteString("<json:") || !WriteString(type)) + return false; + + // For root element, need to add declarations + if (level_ == 0) { + if (!WriteString( + " xsi:schemaLocation=\"http://www.datapower.com/schemas/json jsonx.xsd\"" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + " xmlns:json=\"http://www.ibm.com/xmlns/prod/2009/jsonx\"")) + return false; + } + + if (hasName_) { + hasName_ = false; + if (!WriteString(" name=\"") || + !WriteEscapedAttributeValue(name_.GetString(), name_.GetSize()) || + !WriteString("\"")) + return false; + } + + if (emptyElement) + return WriteString("/>"); + else { + level_++; + return WriteString(">"); + } + } + + bool WriteEndElement(const char* type) { + if (!WriteString("</json:") || + !WriteString(type) || + !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<FileWriteStream> 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<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode())); + return 1; + } + + return 0; +} |