diff --git a/CHANGELOG.md b/CHANGELOG.md
index 06601867..6dddc838 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,8 +27,10 @@
* JSON changes
* Non-pretty-print output removed all extra spaces.
* Example: `{"nacm-example:x": 42}` --> {"nacm-example:x":42}`
- * Empty JSON container changed from `null` to `{}`.
- * Empty list and leafs remain as `null`
+ * Empty JSON values changed from `null` to:
+ * Empty yang container encoded as `{}`
+ * Empty leaf/leaf-list of type empty encoded as `[null]`
+ * Other empty values remain as `null`
### Minor changes
* Removed unnecessary configure dependencies
diff --git a/apps/restconf/restconf_methods_get.c b/apps/restconf/restconf_methods_get.c
index 1fb8ad10..60038c1a 100644
--- a/apps/restconf/restconf_methods_get.c
+++ b/apps/restconf/restconf_methods_get.c
@@ -187,18 +187,17 @@ api_data_get2(clicon_handle h,
}
else{
#if 0
- if (debug){
- cbuf *ccc=cbuf_new();
- if (clicon_xml2cbuf(ccc, xret, 0, 0) < 0)
- goto done;
- clicon_debug(1, "%s xret: %s",
- __FUNCTION__, cbuf_get(ccc));
- cbuf_free(ccc);
+ if (debug){
+ cbuf *ccc=cbuf_new();
+ if (clicon_xml2cbuf(ccc, xret, 0, 0) < 0)
+ goto done;
+ clicon_debug(1, "%s xret: %s",
+ __FUNCTION__, cbuf_get(ccc));
+ cbuf_free(ccc);
}
#endif
-
- if (xml2json_cbuf(cbx, xret, pretty) < 0)
- goto done;
+ if (xml2json_cbuf(cbx, xret, pretty) < 0)
+ goto done;
}
}
else{
diff --git a/lib/src/clixon_json.c b/lib/src/clixon_json.c
index 23c9389b..a89a4162 100644
--- a/lib/src/clixon_json.c
+++ b/lib/src/clixon_json.c
@@ -193,14 +193,14 @@ array_eval(cxobj *xprev,
char *ns2;
nsx = xml_find_type_value(x, NULL, "xmlns", CX_ATTR);
- if (xml_type(x)!=CX_ELMNT){
+ if (xml_type(x) != CX_ELMNT){
array=BODY_ARRAY;
goto done;
}
ys = xml_spec(x);
if (xnext &&
xml_type(xnext)==CX_ELMNT &&
- strcmp(xml_name(x),xml_name(xnext))==0){
+ strcmp(xml_name(x), xml_name(xnext))==0){
ns2 = xml_find_type_value(xnext, NULL, "xmlns", CX_ATTR);
if ((!nsx && !ns2)
|| (nsx && ns2 && strcmp(nsx,ns2)==0))
@@ -420,13 +420,17 @@ json2xml_decode(cxobj *x,
if (keyword == Y_LEAF || keyword == Y_LEAF_LIST){
if (yang_type_get(y, NULL, &ytype, NULL, NULL, NULL, NULL, NULL) < 0)
goto done;
- if (ytype)
+
+ if (ytype){
if (strcmp(yang_argument_get(ytype),"identityref")==0){
if ((ret = json2xml_decode_identityref(x, y, xerr)) < 0)
goto done;
if (ret == 0)
goto fail;
}
+ else if (strcmp(yang_argument_get(ytype), "empty")==0)
+ ; /* dont need to do anything */
+ }
}
}
xc = NULL;
@@ -464,6 +468,7 @@ xml2json_encode_identityref(cxobj *xb,
yang_stmt *yspec;
yang_stmt *my_ymod;
+ clicon_debug(1, "%s %s", __FUNCTION__, body);
my_ymod = ys_module(yp);
yspec = ys_spec(yp);
if (nodeid_split(body, &prefix, &id) < 0)
@@ -667,7 +672,6 @@ xml2json1_cbuf(cbuf *cb,
modname0 = modname; /* modname0 is ancestor ns passed to child */
}
childt = child_type(x);
-
if (pretty==2)
cprintf(cb, "#%s_array, %s_child ",
arraytype2str(arraytype),
@@ -687,12 +691,18 @@ xml2json1_cbuf(cbuf *cb,
switch (childt){
case NULL_CHILD:
/* If x is a container, use {} instead of null
- * That is, x is not a list or leaf
+ * if leaf or leaf-list then assume EMPTY type, then [null]
+ * else null
*/
if (ys && yang_keyword_get(ys) == Y_CONTAINER)
cprintf(cb, "{}");
- else
- cprintf(cb, "null");
+ else{
+ if (ys &&
+ (yang_keyword_get(ys) == Y_LEAF || yang_keyword_get(ys) == Y_LEAF_LIST))
+ cprintf(cb, "[null]");
+ else
+ cprintf(cb, "null");
+ }
break;
case BODY_CHILD:
break;
@@ -756,6 +766,7 @@ xml2json1_cbuf(cbuf *cb,
xc = xml_child_i(x, i);
if (xml_type(xc) == CX_ATTR)
continue; /* XXX Only xmlns attributes mapped */
+
xc_arraytype = array_eval(i?xml_child_i(x,i-1):NULL,
xc,
xml_child_i(x, i+1));
diff --git a/test/test_choice.sh b/test/test_choice.sh
index 5b0d9479..5ead0d93 100755
--- a/test/test_choice.sh
+++ b/test/test_choice.sh
@@ -127,7 +127,6 @@ new "waiting"
wait_backend
wait_restconf
-
# First vanilla (protocol) case
new "netconf validate empty"
expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$"
@@ -171,17 +170,17 @@ new "restconf DELETE whole datastore"
expectfn 'curl -s -X DELETE http://localhost/restconf/data' 0 ""
new "restconf set protocol tcp+udp fail"
-expecteq "$(curl -s -X PUT http://localhost/restconf/data/system:system/protocol -d '{"system:protocol":{"tcp": null, "udp": null}}')" 0 '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"bad-element","error-info":{"bad-element":"udp"},"error-severity":"error","error-message":"Element in choice statement already exists"}}}
'
+expecteq "$(curl -s -X PUT http://localhost/restconf/data/system:system/protocol -d '{"system:protocol":{"tcp": [null], "udp": [null]}}')" 0 '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"bad-element","error-info":{"bad-element":"udp"},"error-severity":"error","error-message":"Element in choice statement already exists"}}}
'
new "restconf set protocol tcp"
-expecteq "$(curl -s -X PUT http://localhost/restconf/data/system:system/protocol -d {\"system:protocol\":{\"tcp\":null}})" 0 ""
+expecteq "$(curl -s -X PUT http://localhost/restconf/data/system:system/protocol -d {\"system:protocol\":{\"tcp\":[null]}})" 0 ""
new "restconf get protocol tcp"
-expecteq "$(curl -s -X GET http://localhost/restconf/data/system:system)" 0 '{"system:system":{"protocol":{"tcp":null}}}
+expecteq "$(curl -s -X GET http://localhost/restconf/data/system:system)" 0 '{"system:system":{"protocol":{"tcp":[null]}}}
'
new "restconf set protocol tcp+udp fail"
-expecteq "$(curl -s -X PUT http://localhost/restconf/data/system:system/protocol -d '{"system:protocol":{"tcp": null, "udp": null}}')" 0 '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"bad-element","error-info":{"bad-element":"udp"},"error-severity":"error","error-message":"Element in choice statement already exists"}}}
'
+expecteq "$(curl -s -X PUT http://localhost/restconf/data/system:system/protocol -d '{"system:protocol":{"tcp": [null], "udp": [null]}}')" 0 '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"bad-element","error-info":{"bad-element":"udp"},"error-severity":"error","error-message":"Element in choice statement already exists"}}}
'
new "cli set protocol udp"
expectfn "$clixon_cli -1 -f $cfg -l o set system protocol udp" 0 "^$"