xml2json dont put doublequotes on numbers and bool values in json
This commit is contained in:
parent
ffe77c9127
commit
2bbf0b8a15
2 changed files with 58 additions and 22 deletions
|
|
@ -191,8 +191,10 @@ array_eval(cxobj *xprev,
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
/*! Escape a json string
|
||||||
json_escape(char *str)
|
*/
|
||||||
|
static char *
|
||||||
|
json_str_escape(char *str)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
char *snew;
|
char *snew;
|
||||||
|
|
@ -231,6 +233,7 @@ json_escape(char *str)
|
||||||
* @param[in] level Indentation level
|
* @param[in] level Indentation level
|
||||||
* @param[in] pretty Pretty-print output (2 means debug)
|
* @param[in] pretty Pretty-print output (2 means debug)
|
||||||
* @param[in] flat Dont print NO_ARRAY object name (for _vec call)
|
* @param[in] flat Dont print NO_ARRAY object name (for _vec call)
|
||||||
|
* @param[in] bodystr Set if value is string, 0 otherwise. Only if body
|
||||||
*
|
*
|
||||||
* @note Does not work with XML attributes
|
* @note Does not work with XML attributes
|
||||||
* The following matrix explains how the mapping is done.
|
* The following matrix explains how the mapping is done.
|
||||||
|
|
@ -266,26 +269,35 @@ xml2json1_cbuf(cbuf *cb,
|
||||||
enum array_element_type arraytype,
|
enum array_element_type arraytype,
|
||||||
int level,
|
int level,
|
||||||
int pretty,
|
int pretty,
|
||||||
int flat)
|
int flat,
|
||||||
|
int bodystr)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int i;
|
int i;
|
||||||
cxobj *xc;
|
cxobj *xc;
|
||||||
enum childtype childt;
|
enum childtype childt;
|
||||||
enum array_element_type xc_arraytype;
|
enum array_element_type xc_arraytype;
|
||||||
|
yang_stmt *ys;
|
||||||
|
int bodystr0=1;
|
||||||
|
|
||||||
childt = childtype(x);
|
childt = childtype(x);
|
||||||
|
ys = xml_spec(x);
|
||||||
if (pretty==2)
|
if (pretty==2)
|
||||||
cprintf(cb, "#%s_array, %s_child ",
|
cprintf(cb, "#%s_array, %s_child ",
|
||||||
arraytype2str(arraytype),
|
arraytype2str(arraytype),
|
||||||
childtype2str(childt));
|
childtype2str(childt));
|
||||||
switch(arraytype){
|
switch(arraytype){
|
||||||
case BODY_ARRAY:{
|
case BODY_ARRAY:{
|
||||||
char *str;
|
if (bodystr){
|
||||||
if ((str = json_escape(xml_value(x))) == NULL)
|
char *str;
|
||||||
goto done;
|
if ((str = json_str_escape(xml_value(x))) == NULL)
|
||||||
cprintf(cb, "\"%s\"", str);
|
goto done;
|
||||||
free(str);
|
cprintf(cb, "\"%s\"", str);
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cprintf(cb, "%s", xml_value(x));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NO_ARRAY:
|
case NO_ARRAY:
|
||||||
|
|
@ -349,6 +361,30 @@ xml2json1_cbuf(cbuf *cb,
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* Check for typed sub-body if:
|
||||||
|
* arracytype=* but chilt-type is BODY_CHILD
|
||||||
|
* This is code for writing <a>42</a> as "a":42 and not "a":"42"
|
||||||
|
*/
|
||||||
|
if (childt == BODY_CHILD && ys!=NULL &&
|
||||||
|
(ys->ys_keyword == Y_LEAF || ys->ys_keyword == Y_LEAF_LIST))
|
||||||
|
switch (cv_type_get(ys->ys_cv)){
|
||||||
|
case CGV_INT8:
|
||||||
|
case CGV_INT16:
|
||||||
|
case CGV_INT32:
|
||||||
|
case CGV_INT64:
|
||||||
|
case CGV_UINT8:
|
||||||
|
case CGV_UINT16:
|
||||||
|
case CGV_UINT32:
|
||||||
|
case CGV_UINT64:
|
||||||
|
case CGV_DEC64:
|
||||||
|
case CGV_BOOL:
|
||||||
|
bodystr0 = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bodystr0 = 1;
|
||||||
|
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);
|
||||||
xc_arraytype = array_eval(i?xml_child_i(x,i-1):NULL,
|
xc_arraytype = array_eval(i?xml_child_i(x,i-1):NULL,
|
||||||
|
|
@ -357,7 +393,7 @@ xml2json1_cbuf(cbuf *cb,
|
||||||
if (xml2json1_cbuf(cb,
|
if (xml2json1_cbuf(cb,
|
||||||
xc,
|
xc,
|
||||||
xc_arraytype,
|
xc_arraytype,
|
||||||
level+1, pretty,0) < 0)
|
level+1, pretty, 0, bodystr0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (i<xml_child_nr(x)-1)
|
if (i<xml_child_nr(x)-1)
|
||||||
cprintf(cb, ",%s", pretty?"\n":"");
|
cprintf(cb, ",%s", pretty?"\n":"");
|
||||||
|
|
@ -456,7 +492,7 @@ xml2json_cbuf(cbuf *cb,
|
||||||
if (xml2json1_cbuf(cb,
|
if (xml2json1_cbuf(cb,
|
||||||
x,
|
x,
|
||||||
NO_ARRAY,
|
NO_ARRAY,
|
||||||
level+1, pretty,0) < 0)
|
level+1, pretty,0,1) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, "%s%*s}%s",
|
cprintf(cb, "%s%*s}%s",
|
||||||
pretty?"\n":"",
|
pretty?"\n":"",
|
||||||
|
|
@ -506,7 +542,7 @@ xml2json_cbuf_vec(cbuf *cb,
|
||||||
if (xml2json1_cbuf(cb,
|
if (xml2json1_cbuf(cb,
|
||||||
xp,
|
xp,
|
||||||
NO_ARRAY,
|
NO_ARRAY,
|
||||||
level+1, pretty,1) < 0)
|
level+1, pretty,1, 1) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (0){
|
if (0){
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ module example{
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# This is a fixed 'state' implemented in routing_backend. It is assumed to be always there
|
# This is a fixed 'state' implemented in routing_backend. It is assumed to be always there
|
||||||
state='{"interfaces-state": {"interface": \[{"name": "eth0","type": "eth","if-index": "42"}\]}}'
|
state='{"interfaces-state": {"interface": \[{"name": "eth0","type": "eth","if-index": 42}\]}}'
|
||||||
|
|
||||||
# kill old backend (if any)
|
# kill old backend (if any)
|
||||||
new "kill old backend"
|
new "kill old backend"
|
||||||
|
|
@ -72,7 +72,7 @@ new "kill old restconf daemon"
|
||||||
sudo pkill -u www-data clixon_restconf
|
sudo pkill -u www-data clixon_restconf
|
||||||
|
|
||||||
new "start restconf daemon"
|
new "start restconf daemon"
|
||||||
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -Df $cfg -D
|
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg -D
|
||||||
|
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
|
|
@ -109,7 +109,7 @@ if [ -z "$match" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "restconf get data/interfaces-state/interface=eth0 json"
|
new "restconf get data/interfaces-state/interface=eth0 json"
|
||||||
expectfn "curl -s -G http://localhost/restconf/data/interfaces-state/interface=eth0" '{"interface": \[{"name": "eth0","type": "eth","if-index": "42"}\]}'
|
expectfn "curl -s -G http://localhost/restconf/data/interfaces-state/interface=eth0" '{"interface": \[{"name": "eth0","type": "eth","if-index": 42}\]}'
|
||||||
|
|
||||||
new "restconf get state operation eth0 xml"
|
new "restconf get state operation eth0 xml"
|
||||||
# Cant get shell macros to work, inline matching from lib.sh
|
# Cant get shell macros to work, inline matching from lib.sh
|
||||||
|
|
@ -134,10 +134,10 @@ if [ -z "$match" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "restconf Add subtree to datastore using POST"
|
new "restconf Add subtree to datastore using POST"
|
||||||
expectfn 'curl -s -X POST -d {"interfaces":{"interface":{"name":"eth/0/0","type":"eth","enabled":"true"}}} http://localhost/restconf/data' ""
|
expectfn 'curl -s -X POST -d {"interfaces":{"interface":{"name":"eth/0/0","type":"eth","enabled":true}}} http://localhost/restconf/data' ""
|
||||||
|
|
||||||
new "restconf Check interfaces eth/0/0 added"
|
new "restconf Check interfaces eth/0/0 added"
|
||||||
expectfn "curl -s -G http://localhost/restconf/data" '{"interfaces": {"interface": \[{"name": "eth/0/0","type": "eth","enabled": "true"}\]},"interfaces-state": {"interface": \[{"name": "eth0","type": "eth","if-index": "42"}\]}}
|
expectfn "curl -s -G http://localhost/restconf/data" '{"interfaces": {"interface": \[{"name": "eth/0/0","type": "eth","enabled": true}\]},"interfaces-state": {"interface": \[{"name": "eth0","type": "eth","if-index": 42}\]}}
|
||||||
$'
|
$'
|
||||||
|
|
||||||
new "restconf delete interfaces"
|
new "restconf delete interfaces"
|
||||||
|
|
@ -147,14 +147,14 @@ new "restconf Check empty config"
|
||||||
expectfn "curl -sG http://localhost/restconf/data" $state
|
expectfn "curl -sG http://localhost/restconf/data" $state
|
||||||
|
|
||||||
new "restconf Add interfaces subtree eth/0/0 using POST"
|
new "restconf Add interfaces subtree eth/0/0 using POST"
|
||||||
expectfn 'curl -s -X POST -d {"interface":{"name":"eth/0/0","type":"eth","enabled":"true"}} http://localhost/restconf/data/interfaces' ""
|
expectfn 'curl -s -X POST -d {"interface":{"name":"eth/0/0","type":"eth","enabled":true}} http://localhost/restconf/data/interfaces' ""
|
||||||
|
|
||||||
new "restconf Check eth/0/0 added"
|
new "restconf Check eth/0/0 added"
|
||||||
expectfn "curl -s -G http://localhost/restconf/data" '{"interfaces": {"interface": \[{"name": "eth/0/0","type": "eth","enabled": "true"}\]},"interfaces-state": {"interface": \[{"name": "eth0","type": "eth","if-index": "42"}\]}}
|
expectfn "curl -s -G http://localhost/restconf/data" '{"interfaces": {"interface": \[{"name": "eth/0/0","type": "eth","enabled": true}\]},"interfaces-state": {"interface": \[{"name": "eth0","type": "eth","if-index": 42}\]}}
|
||||||
$'
|
$'
|
||||||
|
|
||||||
new "restconf Re-post eth/0/0 which should generate error"
|
new "restconf Re-post eth/0/0 which should generate error"
|
||||||
expectfn 'curl -s -X POST -d {"interface":{"name":"eth/0/0","type":"eth","enabled":"true"}} http://localhost/restconf/data/interfaces' "Data resource already exists"
|
expectfn 'curl -s -X POST -d {"interface":{"name":"eth/0/0","type":"eth","enabled":true}} http://localhost/restconf/data/interfaces' "Data resource already exists"
|
||||||
|
|
||||||
new "Add leaf description using POST"
|
new "Add leaf description using POST"
|
||||||
expectfn 'curl -s -X POST -d {"description":"The-first-interface"} http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' ""
|
expectfn 'curl -s -X POST -d {"description":"The-first-interface"} http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' ""
|
||||||
|
|
@ -163,7 +163,7 @@ new "Add nothing using POST"
|
||||||
expectfn 'curl -s -X POST http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' "data is in some way badly formed"
|
expectfn 'curl -s -X POST http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' "data is in some way badly formed"
|
||||||
|
|
||||||
new "restconf Check description added"
|
new "restconf Check description added"
|
||||||
expectfn "curl -s -G http://localhost/restconf/data" '{"interfaces": {"interface": \[{"name": "eth/0/0","description": "The-first-interface","type": "eth","enabled": "true"}\]}
|
expectfn "curl -s -G http://localhost/restconf/data" '{"interfaces": {"interface": \[{"name": "eth/0/0","description": "The-first-interface","type": "eth","enabled": true}\]}
|
||||||
$'
|
$'
|
||||||
|
|
||||||
new "restconf delete eth/0/0"
|
new "restconf delete eth/0/0"
|
||||||
|
|
@ -176,10 +176,10 @@ new "restconf Re-Delete eth/0/0 using none should generate error"
|
||||||
expectfn 'curl -s -X DELETE http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' "Not Found"
|
expectfn 'curl -s -X DELETE http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' "Not Found"
|
||||||
|
|
||||||
new "restconf Add subtree eth/0/0 using PUT"
|
new "restconf Add subtree eth/0/0 using PUT"
|
||||||
expectfn 'curl -s -X PUT -d {"interface":{"name":"eth/0/0","type":"eth","enabled":"true"}} http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' ""
|
expectfn 'curl -s -X PUT -d {"interface":{"name":"eth/0/0","type":"eth","enabled":true}} http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' ""
|
||||||
|
|
||||||
new "restconf get subtree"
|
new "restconf get subtree"
|
||||||
expectfn "curl -s -G http://localhost/restconf/data" '{"interfaces": {"interface": \[{"name": "eth/0/0","type": "eth","enabled": "true"}\]},"interfaces-state": {"interface": \[{"name": "eth0","type": "eth","if-index": "42"}\]}}
|
expectfn "curl -s -G http://localhost/restconf/data" '{"interfaces": {"interface": \[{"name": "eth/0/0","type": "eth","enabled": true}\]},"interfaces-state": {"interface": \[{"name": "eth0","type": "eth","if-index": 42}\]}}
|
||||||
$'
|
$'
|
||||||
|
|
||||||
new "restconf rpc using POST json"
|
new "restconf rpc using POST json"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue