mirror of
https://github.com/Tencent/rapidjson.git
synced 2025-03-09 11:09:32 +01:00
Merge pull request #531 from miloyip/jsonx
Add Jsonx example for converting JSON into JSONx (a XML format)
This commit is contained in:
commit
ef36794336
@ -6,6 +6,7 @@ cmake_minimum_required(VERSION 2.8)
|
||||
set(EXAMPLES
|
||||
capitalize
|
||||
condense
|
||||
jsonx
|
||||
messagereader
|
||||
pretty
|
||||
prettyauto
|
||||
@ -18,6 +19,8 @@ set(EXAMPLES
|
||||
|
||||
include_directories("../include/")
|
||||
|
||||
add_definitions(-D__STDC_FORMAT_MACROS)
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
|
200
example/jsonx/jsonx.cpp
Normal file
200
example/jsonx/jsonx.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
// 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.
|
||||
// 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 <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), 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 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user