From 5c20be7038fe63f4c23f7bd265d3c1fd97f84088 Mon Sep 17 00:00:00 2001 From: "Eduardo Ramos Testillano (eramedu)" Date: Sat, 2 May 2020 14:17:00 +0200 Subject: [PATCH] Add sax converter from json to xml This source is also published at github as: https://github.com/testillano/json2xml --- include/anna/json/SaxConsumer.hpp | 128 ++++++++++++++++++++++++++++++ include/anna/json/functions.hpp | 37 +++++++++ source/json/functions.cpp | 23 ++++++ 3 files changed, 188 insertions(+) create mode 100644 include/anna/json/SaxConsumer.hpp create mode 100644 include/anna/json/functions.hpp create mode 100644 source/json/functions.cpp diff --git a/include/anna/json/SaxConsumer.hpp b/include/anna/json/SaxConsumer.hpp new file mode 100644 index 0000000..110a097 --- /dev/null +++ b/include/anna/json/SaxConsumer.hpp @@ -0,0 +1,128 @@ +// ANNA - Anna is Not Nothingness Anymore // +// // +// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo // +// // +// See project site at http://redmine.teslayout.com/projects/anna-suite // +// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE // + + +#ifndef anna_json_SaxConsumer_hpp +#define anna_json_SaxConsumer_hpp + +#include +#include +#include +#include // nlohmann::json +#include + +namespace anna { + +namespace json { + +class SaxConsumer : public nlohmann::json::json_sax_t +{ + int indent_; + bool started_; + std::stringstream result_; + std::stringstream current_object_; + std::stack nodes_stack_; + + public: + + SaxConsumer() : started_(false), indent_(-ANNA_XML_INDENTATION_SPACES) {} + + const std::stringstream & getResult() const { return result_; } + + bool null() override + { + current_object_ << ""; + return true; + } + + bool boolean(bool val) override + { + current_object_ << std::quoted(val ? "true" : "false"); + return true; + } + + bool number_integer(number_integer_t val) override + { + current_object_ << std::quoted(std::to_string(val)); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + current_object_ << std::quoted(std::to_string(val)); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + current_object_ << std::quoted(s); + return true; + } + + bool string(string_t& val) override + { + current_object_ << std::quoted(val); + return true; + } + + bool start_object(std::size_t elements) override + { + if (!started_) { started_ = true ; return true; } // ignore first start object (which is whole json object {) + indent_ += ANNA_XML_INDENTATION_SPACES; + result_ << std::string(indent_, ' ') << "<" << nodes_stack_.top(); + return true; + } + + bool end_object() override + { + std::string close = "/>"; + if (current_object_.str().empty()) close = ""; + result_ << current_object_.str() << close; + if (indent_ < 0) return true; + indent_ -= ANNA_XML_INDENTATION_SPACES; + if (close == "") result_ << ""; + result_ << "\n"; + current_object_.str(""); + return true; + } + + bool start_array(std::size_t elements) override + { + result_ << current_object_.str() << ">\n"; + current_object_.str(""); + return true; + } + + bool end_array() override + { + result_ << std::string(indent_, ' '); + nodes_stack_.pop(); + return true; + } + + bool key(string_t& val) override + { + if (val[0] != '@') { + nodes_stack_.push(val); + } + else { + current_object_ << " " << val.substr(1) << "="; + } + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const nlohmann::json::exception& ex) override + { + result_ << std::string(ex.what()); + return false; + } +}; + +} +} + +#endif diff --git a/include/anna/json/functions.hpp b/include/anna/json/functions.hpp new file mode 100644 index 0000000..dc055dd --- /dev/null +++ b/include/anna/json/functions.hpp @@ -0,0 +1,37 @@ +// ANNA - Anna is Not Nothingness Anymore // +// // +// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo // +// // +// See project site at http://redmine.teslayout.com/projects/anna-suite // +// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE // + + +#ifndef anna_json_functions_hpp +#define anna_json_functions_hpp + + +#include + + +namespace anna { + +namespace json { + +struct functions { + + /** + Convert json representation into xml equivalent + + @param json Json representation + @param success operation result + + @return xml representation for the json provided + */ + static std::string json2xml(const std::string &json, bool & success); + +}; + +} +} + +#endif diff --git a/source/json/functions.cpp b/source/json/functions.cpp new file mode 100644 index 0000000..1806919 --- /dev/null +++ b/source/json/functions.cpp @@ -0,0 +1,23 @@ +// ANNA - Anna is Not Nothingness Anymore // +// // +// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo // +// // +// See project site at http://redmine.teslayout.com/projects/anna-suite // +// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE // + + +#include +#include + + +std::string anna::json::functions::json2xml(const std::string &json, bool & success) { + + // create a SAX event consumer object + anna::json::SaxConsumer consumer; + + // parse and serialize JSON + success = nlohmann::json::sax_parse(json, &consumer); + + // output the result of sax_parse + return consumer.getResult().str(); +} -- 2.20.1