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
|
set(EXAMPLES
|
||||||
capitalize
|
capitalize
|
||||||
condense
|
condense
|
||||||
|
jsonx
|
||||||
messagereader
|
messagereader
|
||||||
pretty
|
pretty
|
||||||
prettyauto
|
prettyauto
|
||||||
@ -18,6 +19,8 @@ set(EXAMPLES
|
|||||||
|
|
||||||
include_directories("../include/")
|
include_directories("../include/")
|
||||||
|
|
||||||
|
add_definitions(-D__STDC_FORMAT_MACROS)
|
||||||
|
|
||||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default")
|
||||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
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