xml->json translation revisited
This commit is contained in:
parent
3443dbd33f
commit
1c061aaf26
2 changed files with 122 additions and 74 deletions
|
|
@ -28,7 +28,8 @@
|
||||||
*/
|
*/
|
||||||
int json_parse_str(char *str, cxobj **xt);
|
int json_parse_str(char *str, cxobj **xt);
|
||||||
int xml2json_cbuf(cbuf *cb, cxobj *x, int pretty);
|
int xml2json_cbuf(cbuf *cb, cxobj *x, int pretty);
|
||||||
int xml2json_cbuf_vec(cbuf *cb, cxobj **vec, size_t veclen, int pretty);
|
int xml2json_cbuf_vec(cbuf *cb, cxobj **vec, size_t veclen, int pretty);
|
||||||
int xml2json(FILE *f, cxobj *x, int pretty);
|
int xml2json(FILE *f, cxobj *x, int pretty);
|
||||||
|
int xml2json_vec(FILE *f, cxobj **vec, size_t veclen, int pretty);
|
||||||
|
|
||||||
#endif /* _CLIXON_JSON_H */
|
#endif /* _CLIXON_JSON_H */
|
||||||
|
|
|
||||||
|
|
@ -139,35 +139,23 @@ enum list_element_type{
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum list_element_type
|
static enum list_element_type
|
||||||
list_eval(cxobj *x)
|
list_eval(cxobj *xprev,
|
||||||
|
cxobj *x,
|
||||||
|
cxobj *xnext)
|
||||||
{
|
{
|
||||||
enum list_element_type list = LIST_NO;
|
enum list_element_type list = LIST_NO;
|
||||||
cxobj *xp;
|
|
||||||
cxobj *xprev=NULL;
|
|
||||||
cxobj *xnext=NULL;
|
|
||||||
int i;
|
|
||||||
int eqprev=0;
|
int eqprev=0;
|
||||||
int eqnext=0;
|
int eqnext=0;
|
||||||
|
|
||||||
assert(xml_type(x)==CX_ELMNT);
|
assert(xml_type(x)==CX_ELMNT);
|
||||||
if ((xp = xml_parent(x)) == NULL)
|
if (xnext &&
|
||||||
goto done;
|
xml_type(xnext)==CX_ELMNT &&
|
||||||
for (i=0; i<xml_child_nr(xp); i++)
|
strcmp(xml_name(x),xml_name(xnext))==0)
|
||||||
if (x == xml_child_i(xp, i))
|
|
||||||
break;
|
|
||||||
assert(i<xml_child_nr(xp));
|
|
||||||
if (i < xml_child_nr(xp)-1){
|
|
||||||
xnext = xml_child_i(xp, i+1);
|
|
||||||
if (xml_type(xnext)==CX_ELMNT &&
|
|
||||||
strcmp(xml_name(x),xml_name(xnext))==0)
|
|
||||||
eqnext++;
|
eqnext++;
|
||||||
}
|
if (xprev &&
|
||||||
if (i){
|
xml_type(xprev)==CX_ELMNT &&
|
||||||
xprev = xml_child_i(xp, i-1);
|
strcmp(xml_name(x),xml_name(xprev))==0)
|
||||||
if (xml_type(xprev)==CX_ELMNT &&
|
eqprev++;
|
||||||
strcmp(xml_name(x),xml_name(xprev))==0)
|
|
||||||
eqprev++;
|
|
||||||
}
|
|
||||||
if (eqprev && eqnext)
|
if (eqprev && eqnext)
|
||||||
list = LIST_MIDDLE;
|
list = LIST_MIDDLE;
|
||||||
else if (eqprev)
|
else if (eqprev)
|
||||||
|
|
@ -176,7 +164,7 @@ list_eval(cxobj *x)
|
||||||
list = LIST_FIRST;
|
list = LIST_FIRST;
|
||||||
else
|
else
|
||||||
list = LIST_NO;
|
list = LIST_NO;
|
||||||
done:
|
// done:
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,7 +176,9 @@ list_eval(cxobj *x)
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
xml2json1_cbuf(cbuf *cb,
|
xml2json1_cbuf(cbuf *cb,
|
||||||
|
cxobj *xprev,
|
||||||
cxobj *x,
|
cxobj *x,
|
||||||
|
cxobj *xnext,
|
||||||
int level,
|
int level,
|
||||||
int pretty)
|
int pretty)
|
||||||
{
|
{
|
||||||
|
|
@ -205,25 +195,29 @@ xml2json1_cbuf(cbuf *cb,
|
||||||
cprintf(cb, "null");
|
cprintf(cb, "null");
|
||||||
break;
|
break;
|
||||||
case CX_ELMNT:
|
case CX_ELMNT:
|
||||||
list = list_eval(x);
|
list = list_eval(xprev, x, xnext);
|
||||||
switch (list){
|
switch (list){
|
||||||
case LIST_NO:
|
case LIST_NO:
|
||||||
cprintf(cb, "%*s\"%s\": ",
|
cprintf(cb, "%*s\"%s\": ",
|
||||||
pretty?(level*JSON_INDENT):0, "",
|
pretty?(level*JSON_INDENT):0, "",
|
||||||
xml_name(x));
|
xml_name(x));
|
||||||
if (!tleaf(x))
|
if (!tleaf(x)){
|
||||||
cprintf(cb, "{%s",
|
if (xml_child_nr(x))
|
||||||
pretty?"\n":"");
|
cprintf(cb, "{%s",
|
||||||
|
pretty?"\n":"");
|
||||||
|
else
|
||||||
|
cprintf(cb, "null");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case LIST_FIRST:
|
case LIST_FIRST:
|
||||||
cprintf(cb, "%*s\"%s\": [%s",
|
cprintf(cb, "%*s\"%s\": [%s%*s",
|
||||||
pretty?(level*JSON_INDENT):0, "",
|
pretty?(level*JSON_INDENT):0, "",
|
||||||
xml_name(x),
|
xml_name(x),
|
||||||
pretty?"\n":"");
|
pretty?"\n":"",
|
||||||
|
pretty?((level+1)*JSON_INDENT):0, "");
|
||||||
|
level++;
|
||||||
if (!tleaf(x)){
|
if (!tleaf(x)){
|
||||||
level++;
|
cprintf(cb, "{%s",
|
||||||
cprintf(cb, "%*s{%s",
|
|
||||||
pretty?(level*JSON_INDENT):0, "",
|
|
||||||
pretty?"\n":"");
|
pretty?"\n":"");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -233,38 +227,51 @@ xml2json1_cbuf(cbuf *cb,
|
||||||
cprintf(cb, "%*s",
|
cprintf(cb, "%*s",
|
||||||
pretty?(level*JSON_INDENT):0, "");
|
pretty?(level*JSON_INDENT):0, "");
|
||||||
if (!tleaf(x))
|
if (!tleaf(x))
|
||||||
cprintf(cb, "{%s",
|
cprintf(cb, "{ %s", pretty?"\n":"");
|
||||||
pretty?"\n":"");
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (i=0; i<xml_child_nr(x); i++){
|
for (i=0; i<xml_child_nr(x); i++){
|
||||||
xc = xml_child_i(x, i);
|
xc = xml_child_i(x, i);
|
||||||
if (xml2json1_cbuf(cb, xc, level+1, pretty) < 0)
|
if (xml2json1_cbuf(cb,
|
||||||
|
i?xml_child_i(x,i-1):NULL,
|
||||||
|
xc,
|
||||||
|
xml_child_i(x, i+1),
|
||||||
|
level+1, pretty) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (i<xml_child_nr(x)-1){
|
if (i<xml_child_nr(x)-1){
|
||||||
cprintf(cb, ",");
|
cprintf(cb, ",");
|
||||||
cprintf(cb, "%s", pretty?"\n":"");
|
if (pretty)
|
||||||
|
cprintf(cb, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (list){
|
switch (list){
|
||||||
case LIST_NO:
|
case LIST_NO:
|
||||||
if (!tleaf(x)){
|
if (!tleaf(x)){
|
||||||
if (pretty)
|
if (xml_child_nr(x)){
|
||||||
cprintf(cb, "%*s}\n",
|
if (pretty)
|
||||||
(level*JSON_INDENT), "");
|
cprintf(cb, "\n%*s}",
|
||||||
else
|
(level*JSON_INDENT), "");
|
||||||
cprintf(cb, "}");
|
else
|
||||||
|
cprintf(cb, "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LIST_FIRST:
|
||||||
|
if (!tleaf(x)){
|
||||||
|
cprintf(cb, "%s%*s}",
|
||||||
|
pretty?"\n":"",
|
||||||
|
pretty?(level*JSON_INDENT):0, "");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LIST_MIDDLE:
|
case LIST_MIDDLE:
|
||||||
case LIST_FIRST:
|
if (!tleaf(x))
|
||||||
if (pretty)
|
cprintf(cb, "%s%*s}%s%*s",
|
||||||
cprintf(cb, "\n%*s}",
|
pretty?"\n":"",
|
||||||
(level*JSON_INDENT), "");
|
pretty?(level*JSON_INDENT):0, "",
|
||||||
else
|
pretty?"\n":"",
|
||||||
cprintf(cb, "}");
|
pretty?(level*JSON_INDENT):0, "");
|
||||||
break;
|
break;
|
||||||
case LIST_LAST:
|
case LIST_LAST:
|
||||||
if (!tleaf(x)){
|
if (!tleaf(x)){
|
||||||
|
|
@ -275,9 +282,11 @@ xml2json1_cbuf(cbuf *cb,
|
||||||
cprintf(cb, "}");
|
cprintf(cb, "}");
|
||||||
level--;
|
level--;
|
||||||
}
|
}
|
||||||
cprintf(cb, "%*s]%s",
|
else
|
||||||
pretty?(level*JSON_INDENT):0,"",
|
if (pretty)
|
||||||
pretty?"\n":"");
|
cprintf(cb, "\n");
|
||||||
|
cprintf(cb, "%*s]",
|
||||||
|
pretty?((level-1)*JSON_INDENT):0,"");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -317,14 +326,20 @@ xml2json_cbuf(cbuf *cb,
|
||||||
int retval = 1;
|
int retval = 1;
|
||||||
int level = 0;
|
int level = 0;
|
||||||
|
|
||||||
cprintf(cb, "%*s{%s",
|
if (pretty)
|
||||||
pretty?(level*JSON_INDENT):0,"",
|
cprintf(cb, "%*s{\n", level*JSON_INDENT,"");
|
||||||
pretty?"\n":"");
|
else
|
||||||
if (xml2json1_cbuf(cb, x, level+1, pretty) < 0)
|
cprintf(cb, "{");
|
||||||
|
if (xml2json1_cbuf(cb,
|
||||||
|
NULL,
|
||||||
|
x,
|
||||||
|
NULL,
|
||||||
|
level+1, pretty) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, "%*s}%s",
|
if (pretty)
|
||||||
pretty?(level*JSON_INDENT):0,"",
|
cprintf(cb, "\n%*s}\n", level*JSON_INDENT,"");
|
||||||
pretty?"\n":"");
|
else
|
||||||
|
cprintf(cb, "}");
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
|
|
@ -339,32 +354,41 @@ xml2json_cbuf_vec(cbuf *cb,
|
||||||
size_t veclen,
|
size_t veclen,
|
||||||
int pretty)
|
int pretty)
|
||||||
{
|
{
|
||||||
int retval = 1;
|
int retval = -1;
|
||||||
int level = 0;
|
int level = 0;
|
||||||
int i;
|
int i;
|
||||||
cxobj *xc;
|
cxobj *xc;
|
||||||
|
|
||||||
cprintf(cb, "%*s{%s",
|
if (pretty)
|
||||||
pretty?(level*JSON_INDENT):0,"",
|
cprintf(cb, "%*s[\n",
|
||||||
pretty?"\n":"");
|
level*JSON_INDENT,"");
|
||||||
|
else
|
||||||
|
cprintf(cb, "[");
|
||||||
|
level++;
|
||||||
for (i=0; i<veclen; i++){
|
for (i=0; i<veclen; i++){
|
||||||
xc = vec[i];
|
xc = vec[i];
|
||||||
if (xml2json1_cbuf(cb, xc, level, pretty) < 0)
|
if (xml2json1_cbuf(cb,
|
||||||
|
i?vec[i-1]:NULL,
|
||||||
|
xc,
|
||||||
|
i<veclen-1?vec[i+1]:NULL,
|
||||||
|
level, pretty) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (i<veclen-1){
|
if (i<veclen-1){
|
||||||
if (xml_type(xc)==CX_BODY)
|
cprintf(cb, ",");
|
||||||
cprintf(cb, "},{");
|
if (pretty)
|
||||||
else
|
cprintf(cb, "\n");
|
||||||
cprintf(cb, ",");
|
|
||||||
cprintf(cb, "%s", pretty?"\n":"");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cprintf(cb, "%*s}%s",
|
level--;
|
||||||
pretty?(level*JSON_INDENT):0,"",
|
if (pretty)
|
||||||
pretty?"\n":"");
|
cprintf(cb, "\n%*s]\n",
|
||||||
|
level*JSON_INDENT,"");
|
||||||
|
else
|
||||||
|
cprintf(cb, "]");
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Translate from xml tree to JSON and print to file
|
/*! Translate from xml tree to JSON and print to file
|
||||||
|
|
@ -381,9 +405,9 @@ xml2json_cbuf_vec(cbuf *cb,
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml2json(FILE *f,
|
xml2json(FILE *f,
|
||||||
cxobj *x,
|
cxobj *x,
|
||||||
int pretty)
|
int pretty)
|
||||||
{
|
{
|
||||||
int retval = 1;
|
int retval = 1;
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
|
|
@ -402,6 +426,29 @@ xml2json(FILE *f,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xml2json_vec(FILE *f,
|
||||||
|
cxobj **vec,
|
||||||
|
size_t veclen,
|
||||||
|
int pretty)
|
||||||
|
{
|
||||||
|
int retval = 1;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
|
||||||
|
if ((cb = cbuf_new()) ==NULL){
|
||||||
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (xml2json_cbuf_vec(cb, vec, veclen, pretty) < 0)
|
||||||
|
goto done;
|
||||||
|
fprintf(f, "%s", cbuf_get(cb));
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Parse a string containing JSON and return an XML tree
|
/*! Parse a string containing JSON and return an XML tree
|
||||||
* @param[in] str Input string containing JSON
|
* @param[in] str Input string containing JSON
|
||||||
* @param[in] name Log string, typically filename
|
* @param[in] name Log string, typically filename
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue