more XML to JSON

This commit is contained in:
Olof Hagsand 2016-10-02 12:09:36 +02:00
parent 831ab1be30
commit 7062a75fd7
2 changed files with 90 additions and 86 deletions

View file

@ -166,40 +166,42 @@ array_eval(cxobj *xprev,
* @param[in] arraytype Does x occur in a array (of its parent) and how?
* @param[in] level Indentation level
* @param[in] pretty Pretty-print output (2 means debug)
* @param[in] flat Dont print NO_ARRAY object name (for _vec call)
*
* The following matrix explains how the mapping is done.
* You need to understand what arraytype means (no/first/middle/last)
* and what childtype is (null,body,any)
+---------+--------------+--------------+--------------+
|array,leaf| null | body | any |
+---------+--------------+--------------+--------------+
|no | <a/> |<a>1</a> |<a><b/></a> |
| | | | |
| json: |\ta:null |\ta: |\ta:{\n |
| | | |\n} |
+---------+--------------+--------------+--------------+
|first |<a/><a.. |<a>1</a><a.. |<a><b/></a><a.|
| | | | |
| json: |\ta:[\n\tnull |\ta:[\n\t |\ta:[\n\t{\n |
| | | |\n\t} |
+---------+--------------+--------------+--------------+
|middle |..a><a/><a.. |.a><a>1</a><a.| |
| | | | |
| json: |\tnull |\t |\t{a |
| | | |\n\t} |
+---------+--------------+--------------+--------------+
|last |..a></a> |..a><a>1</a> | |
| | | | |
| json: |\tnull |\t |\t{a |
| |\n\t] |\n\t] |\n\t}\t] |
+---------+--------------+--------------+--------------+
+---------+--------------+--------------+--------------+
|array,leaf| null | body | any |
+---------+--------------+--------------+--------------+
|no | <a/> |<a>1</a> |<a><b/></a> |
| | | | |
| json: |\ta:null |\ta: |\ta:{\n |
| | | |\n} |
+---------+--------------+--------------+--------------+
|first |<a/><a.. |<a>1</a><a.. |<a><b/></a><a.|
| | | | |
| json: |\ta:[\n\tnull |\ta:[\n\t |\ta:[\n\t{\n |
| | | |\n\t} |
+---------+--------------+--------------+--------------+
|middle |..a><a/><a.. |.a><a>1</a><a.| |
| | | | |
| json: |\tnull |\t |\t{a |
| | | |\n\t} |
+---------+--------------+--------------+--------------+
|last |..a></a> |..a><a>1</a> | |
| | | | |
| json: |\tnull |\t |\t{a |
| |\n\t] |\n\t] |\n\t}\t] |
+---------+--------------+--------------+--------------+
*/
static int
xml2json1_cbuf(cbuf *cb,
cxobj *x,
enum array_element_type arraytype,
int level,
int pretty)
int pretty,
int flat)
{
int retval = -1;
int i;
@ -217,6 +219,7 @@ xml2json1_cbuf(cbuf *cb,
cprintf(cb, "\"%s\"", xml_value(x));
break;
case NO_ARRAY:
if (!flat)
cprintf(cb, "%*s\"%s\": ",
pretty?(level*JSON_INDENT):0, "",
xml_name(x));
@ -284,7 +287,7 @@ xml2json1_cbuf(cbuf *cb,
if (xml2json1_cbuf(cb,
xc,
xc_arraytype,
level+1, pretty) < 0)
level+1, pretty,0) < 0)
goto done;
if (i<xml_child_nr(x)-1)
cprintf(cb, ",%s", pretty?"\n":"");
@ -376,26 +379,36 @@ xml2json_cbuf(cbuf *cb,
int retval = 1;
int level = 0;
if (pretty)
cprintf(cb, "%*s{\n", level*JSON_INDENT,"");
else
cprintf(cb, "{");
cprintf(cb, "%*s{%s",
pretty?level*JSON_INDENT:0,"",
pretty?"\n":"");
if (xml2json1_cbuf(cb,
x,
NO_ARRAY,
level+1, pretty) < 0)
level+1, pretty,0) < 0)
goto done;
if (pretty)
cprintf(cb, "\n%*s}\n", level*JSON_INDENT,"");
else
cprintf(cb, "}");
cprintf(cb, "%s%*s}%s",
pretty?"\n":"",
pretty?level*JSON_INDENT:0,"",
pretty?"\n":"");
retval = 0;
done:
return retval;
}
/*! Translate a vectro of xml objects to xml by adding a top pseudo-object.
* example: <b/><c/> --> <a><b/><c/></a> --> {"a" : {"b" : null,"c" : null}}
/*! Translate a vector of xml objects to JSON CLigen buffer.
* This is done by adding a top pseudo-object, and add the vector as subs,
* and then not pritning the top pseudo-.object using the 'flat' option.
* @param[out] cb Cligen buffer to write to
* @param[in] vec Vector of xml objecst
* @param[in] veclen Length of vector
* @param[in] pretty Set if output is pretty-printed (2 for debug)
* @retval 0 OK
* @retval -1 Error
* @note This only works if the vector is uniform, ie same object name.
* Example: <b/><c/> --> <a><b/><c/></a> --> {"b" : null,"c" : null}
* @see xml2json1_cbuf
*/
int
xml2json_cbuf_vec(cbuf *cb,
@ -406,64 +419,42 @@ xml2json_cbuf_vec(cbuf *cb,
int retval = -1;
int level = 0;
int i;
cxobj *xp = NULL;
cxobj *xc;
enum array_element_type arraytype;
#ifdef VEC_ARRAY
if ((xp = xml_new("", NULL)) == NULL)
goto done;
for (i=0; i<veclen; i++){
xc = xml_dup(vec[i]);
xml_addsub(xp, xc);
}
if (0){
cprintf(cb, "[%s", pretty?"\n":" ");
level++;
#else /* pseudo object */
/* Note: We add a pseudo-object on top of the vector.
* This object is array_element_type == NO_ARRAY in xml2json1_cbuf
* and child_type == ANY_CHILD
*/
cprintf(cb, "{%s",
pretty?"\n":" ");
level++;
cprintf(cb, "%*s\"top\": ", /* NO_ARRAY */
pretty?(level*JSON_INDENT):0, "");
cprintf(cb, "{%s", pretty?"\n":""); /* ANY_CHILD */
#endif
for (i=0; i<veclen; i++){
xc = vec[i];
arraytype = array_eval(i?vec[i-1]:NULL,
xc,
i<veclen-1?vec[i+1]:NULL);
}
if (xml2json1_cbuf(cb,
xc,
arraytype,
level, pretty) < 0)
xp,
NO_ARRAY,
level+1, pretty,1) < 0)
goto done;
if (i<veclen-1){
cprintf(cb, ",");
if (pretty)
cprintf(cb, "\n");
}
}
if (0){
level--;
#ifdef VEC_ARRAY
cprintf(cb, "%s]%s",
pretty?"\n":"",
pretty?"\n":""); /* top object */
#else /* pseudo object */
cprintf(cb, "%s%*s}",
pretty?"\n":"",
pretty?(level*JSON_INDENT):0, "");
cprintf(cb, "%s}%s",
pretty?"\n":"",
pretty?"\n":""); /* top object */
#endif
}
retval = 0;
done:
if (xp)
xml_free(xp);
return retval;
}
/*! Translate from xml tree to JSON and print to file
* @param[in] f File to print to
* @param[in] x XML tree to translate from
* @param[in] pretty Set if output is pretty-printed
* @param[in] top By default only children are printed, set if include top
* @retval 0 OK
* @retval -1 Error
*
@ -494,6 +485,19 @@ xml2json(FILE *f,
return retval;
}
/*! Translate a vector of xml objects to JSON File.
* This is done by adding a top pseudo-object, and add the vector as subs,
* and then not pritning the top pseudo-.object using the 'flat' option.
* @param[out] cb Cligen buffer to write to
* @param[in] vec Vector of xml objecst
* @param[in] veclen Length of vector
* @param[in] pretty Set if output is pretty-printed (2 for debug)
* @retval 0 OK
* @retval -1 Error
* @note This only works if the vector is uniform, ie same object name.
* Example: <b/><c/> --> <a><b/><c/></a> --> {"b" : null,"c" : null}
* @see xml2json1_cbuf
*/
int
xml2json_vec(FILE *f,
cxobj **vec,

View file

@ -519,7 +519,7 @@ xml_find(cxobj *x_up,
return NULL;
}
/*! Add xc as child to xp. Remove xc from previous parent.
/*! Append xc as child to xp. Remove xc from previous parent.
* @param[in] xp Parent xml node
* @param[in] xc Child xml node to insert under xp
* @retval 0 OK