From 731ac5c8e6be587589d26011dfac3ca3da253f60 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sun, 4 Oct 2020 15:30:50 +0000 Subject: [PATCH] Feature: Added a basic outline of how converting could happen with a first generic mapping format --- src/xml2json.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/xml2json.h | 4 +++ 2 files changed, 96 insertions(+) diff --git a/src/xml2json.c b/src/xml2json.c index 1d9cdbb4..17c120ba 100644 --- a/src/xml2json.c +++ b/src/xml2json.c @@ -19,3 +19,95 @@ #include "logging.h" #define CATMODULE "xml2json" + +static void render_node(json_renderer_t *renderer, xmlDocPtr doc, xmlNodePtr node, xmlNodePtr parent) +{ + json_renderer_begin(renderer, JSON_ELEMENT_TYPE_OBJECT); + + json_renderer_write_key(renderer, "type", JSON_RENDERER_FLAGS_NONE); + switch (node->type) { + case XML_ELEMENT_NODE: + json_renderer_write_string(renderer, "element", JSON_RENDERER_FLAGS_NONE); + if (node->name) { + json_renderer_write_key(renderer, "name", JSON_RENDERER_FLAGS_NONE); + json_renderer_write_string(renderer, (const char *)node->name, JSON_RENDERER_FLAGS_NONE); + } + break; + case XML_TEXT_NODE: + json_renderer_write_string(renderer, "text", JSON_RENDERER_FLAGS_NONE); + break; + case XML_COMMENT_NODE: + json_renderer_write_string(renderer, "comment", JSON_RENDERER_FLAGS_NONE); + break; + default: + json_renderer_write_null(renderer); + break; + } + + if (node->content) { + json_renderer_write_key(renderer, "text", JSON_RENDERER_FLAGS_NONE); + json_renderer_write_string(renderer, (const char *)node->content, JSON_RENDERER_FLAGS_NONE); + } + + json_renderer_write_key(renderer, "ns", JSON_RENDERER_FLAGS_NONE); + if (node->ns && node->ns->href) { + json_renderer_write_string(renderer, (const char *)node->ns->href, JSON_RENDERER_FLAGS_NONE); + if (node->ns->prefix) { + json_renderer_write_key(renderer, "nsprefix", JSON_RENDERER_FLAGS_NONE); + json_renderer_write_string(renderer, (const char *)node->ns->prefix, JSON_RENDERER_FLAGS_NONE); + } + } else { + json_renderer_write_null(renderer); + } + + if (node->properties) { + xmlAttrPtr cur = node->properties; + + json_renderer_write_key(renderer, "properties", JSON_RENDERER_FLAGS_NONE); + json_renderer_begin(renderer, JSON_ELEMENT_TYPE_OBJECT); + do { + xmlChar *value = xmlNodeListGetString(doc, cur->children, 1); + if (value) { + json_renderer_write_key(renderer, (const char*)cur->name, JSON_RENDERER_FLAGS_NONE); + json_renderer_write_string(renderer, (const char*)value, JSON_RENDERER_FLAGS_NONE); + xmlFree(value); + } + } while ((cur = cur->next)); + json_renderer_end(renderer); + } + + if (node->xmlChildrenNode) { + xmlNodePtr cur = node->xmlChildrenNode; + + json_renderer_write_key(renderer, "children", JSON_RENDERER_FLAGS_NONE); + json_renderer_begin(renderer, JSON_ELEMENT_TYPE_ARRAY); + do { + render_node(renderer, doc, cur, node); + cur = cur->next; + } while (cur); + json_renderer_end(renderer); + } + + json_renderer_end(renderer); +} + +char * xml2json_render_doc_simple(xmlDocPtr doc) +{ + json_renderer_t *renderer; + xmlNodePtr xmlroot; + + if (!doc) + return NULL; + + renderer = json_renderer_create(JSON_RENDERER_FLAGS_NONE); + if (!renderer) + return NULL; + + xmlroot = xmlDocGetRootElement(doc); + if (!xmlroot) + return NULL; + + render_node(renderer, doc, xmlroot, NULL); + + return json_renderer_finish(&renderer); +} diff --git a/src/xml2json.h b/src/xml2json.h index 4a1fee04..c49828b4 100644 --- a/src/xml2json.h +++ b/src/xml2json.h @@ -11,4 +11,8 @@ #ifndef __XML2JSON_H__ #define __XML2JSON_H__ +#include + +char * xml2json_render_doc_simple(xmlDocPtr doc); + #endif