Add sax converter from json to xml
authorEduardo Ramos Testillano (eramedu) <eduardo.ramos.testillano@ericsson.com>
Sat, 2 May 2020 12:17:00 +0000 (14:17 +0200)
committerEduardo Ramos Testillano (eramedu) <eduardo.ramos.testillano@ericsson.com>
Sat, 2 May 2020 12:17:00 +0000 (14:17 +0200)
This source is also published at github as:
https://github.com/testillano/json2xml

include/anna/json/SaxConsumer.hpp [new file with mode: 0644]
include/anna/json/functions.hpp [new file with mode: 0644]
source/json/functions.cpp [new file with mode: 0644]

diff --git a/include/anna/json/SaxConsumer.hpp b/include/anna/json/SaxConsumer.hpp
new file mode 100644 (file)
index 0000000..110a097
--- /dev/null
@@ -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 <iomanip>
+#include <sstream>
+#include <stack>
+#include <anna/json/json.hpp> // nlohmann::json
+#include <anna/core/util/defines.hpp>
+
+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<std::string> nodes_stack_;
+
+  public:
+
+  SaxConsumer() : started_(false), indent_(-ANNA_XML_INDENTATION_SPACES) {}
+
+  const std::stringstream & getResult() const { return result_; }
+
+  bool null() override
+  {
+    current_object_ << "<null>";
+    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_ << "</" << nodes_stack_.top() << ">";
+    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 (file)
index 0000000..dc055dd
--- /dev/null
@@ -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 <anna/json/SaxConsumer.hpp>
+
+
+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 (file)
index 0000000..1806919
--- /dev/null
@@ -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 <anna/json/functions.hpp>
+#include <anna/json/SaxConsumer.hpp>
+
+
+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();
+}