00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include "autoconfig.h"
00034 #endif
00035
00036 #include "xml_to_json.h"
00037 #include "tools.h"
00038
00039 using namespace zmm;
00040 using namespace mxml;
00041
00042 String XML2JSON::getJSON(Ref<Element> root)
00043 {
00044 Ref<StringBuffer> buf(new StringBuffer());
00045 *buf << '{';
00046 handleElement(buf, root);
00047 *buf << '}';
00048 return buf->toString();
00049 }
00050
00051
00052 void XML2JSON::handleElement(Ref<StringBuffer> buf, Ref<Element> el)
00053 {
00054 bool firstChild = true;
00055 int attributeCount = el->attributeCount();
00056 if (attributeCount > 0)
00057 {
00058 for (int i = 0; i < attributeCount; i++)
00059 {
00060 Ref<Attribute> at = el->getAttribute(i);
00061 if (! firstChild)
00062 *buf << ',';
00063 else
00064 firstChild = false;
00065 *buf << '"' << escape(at->name, '\\', '"') << "\":" << getValue(at->value, at->getVType());
00066 }
00067 }
00068
00069 bool array = el->isArrayType();
00070 String nodeName = nil;
00071
00072 if (array)
00073 {
00074 nodeName = el->getArrayName();
00075 if (! string_ok(nodeName))
00076 throw _Exception(_("XML2JSON: Element ") + el->getName() + " was of arrayType, but had no arrayName set");
00077
00078 if (! firstChild)
00079 *buf << ',';
00080 *buf << '"' << escape(nodeName, '\\', '"') << "\":";
00081 *buf << '[';
00082 firstChild = true;
00083 }
00084
00085 int childCount = el->childCount();
00086
00087 for (int i = 0; i < childCount; i++)
00088 {
00089 Ref<Node> node = el->getChild(i);
00090 mxml_node_types type = node->getType();
00091 if (type != mxml_node_element)
00092 {
00093 if (childCount == 1 && type == mxml_node_text)
00094 {
00095 if (! firstChild)
00096 *buf << ',';
00097 else
00098 firstChild = false;
00099 String key = el->getTextKey();
00100 if (! string_ok(key))
00101 throw _Exception(_("XML2JSON: Element ") + el->getName() + " had a text child, but had no textKey set");
00102
00103
00104 *buf << '"' << key << "\":" << getValue(el->getText(), el->getVTypeText());
00105 }
00106 else
00107 throw _Exception(_("XML2JSON cannot handle an element which consists of text AND element children - element: ") + el->getName() + "; has type: " + type);
00108 }
00109 else
00110 {
00111 if (! firstChild)
00112 *buf << ',';
00113 else
00114 firstChild = false;
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 Ref<Element> childEl = RefCast(node, Element);
00145 int childAttributeCount = childEl->attributeCount();
00146 int childElementCount = childEl->elementChildCount();
00147
00148 if (array)
00149 {
00150 if (nodeName != childEl->getName())
00151 throw _Exception(_("XML2JSON: if an element is of arrayType, all children have to have the same name"));
00152 }
00153 else
00154 *buf << '"' << escape(childEl->getName(), '\\', '"') << "\":";
00155
00156 if (childAttributeCount > 0 || childElementCount > 0 || childEl->isArrayType())
00157 {
00158 *buf << '{';
00159 handleElement(buf, childEl);
00160 *buf << '}';
00161 }
00162 else
00163 {
00164 *buf << getValue(childEl->getText(), childEl->getVTypeText());
00165 }
00166 }
00167 }
00168
00169 if (array)
00170 *buf << ']';
00171
00172 }
00173
00174 String XML2JSON::getValue(String text, enum mxml_value_type type)
00175 {
00176 if (type == mxml_string_type)
00177 return _("\"") + escape(text, '\\', '"') + '"';
00178 if (type == mxml_bool_type)
00179 {
00180 assert(string_ok(text));
00181 assert(text == "0" || text == "1");
00182 return text == "0" ? _("false") : _("true");
00183 }
00184 if (type == mxml_null_type)
00185 {
00186 assert(! string_ok(text));
00187 return _("null");
00188 }
00189
00190 if (type == mxml_int_type)
00191 {
00193 return text;
00194 }
00195 return nil;
00196 }