diff --git a/CHANGELOG.md b/CHANGELOG.md
index 593e8f14..b292de24 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -65,6 +65,8 @@ Users may have to change how they access the system
### Corrected Bugs
+* Fixed problems with XPATH composite operations and functions in netconf get/get-config operations.
+ * See [XPATH issues #219](https://github.com/clicon/clixon/issues/219)
* Fix Union in xpath [XPATH issues #219](https://github.com/clicon/clixon/issues/219)
* Fix: XPath:s used in netconf (eg get-config) did not correctly access default values
* [RESTCONF GET request of single-key list with empty string returns all elements #213](https://github.com/clicon/clixon/issues/213)
diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c
index 5be20e27..03d08f57 100644
--- a/lib/src/clixon_xpath.c
+++ b/lib/src/clixon_xpath.c
@@ -239,7 +239,7 @@ xpath_tree_print(FILE *f,
* @param[in] xs XPATH tree
* @param[out] xpath XPath string as CLIgen buf
* @see xpath_tree_print
- * @note NOT COMPLETE, just simple xpaths eg a/b
+ * @note XXX Not complete
*/
int
xpath_tree2cbuf(xpath_tree *xs,
@@ -248,22 +248,11 @@ xpath_tree2cbuf(xpath_tree *xs,
int retval = -1;
switch (xs->xs_type){
- case XP_NODE: /* s0 is namespace prefix, s1 is name */
- if (xs->xs_s0)
- cprintf(xcb, "%s:", xs->xs_s0);
- cprintf(xcb, "%s", xs->xs_s1);
- break;
case XP_ABSPATH:
if (xs->xs_int == A_DESCENDANT_OR_SELF)
cprintf(xcb, "/");
cprintf(xcb, "/");
break;
- case XP_PRIME_STR:
- cprintf(xcb, "'%s'", xs->xs_s0?xs->xs_s0:"");
- break;
- case XP_PRIME_NR:
- cprintf(xcb, "%s", xs->xs_strnr?xs->xs_strnr:"0");
- break;
case XP_STEP:
switch (xs->xs_int){
case A_SELF:
@@ -276,12 +265,34 @@ xpath_tree2cbuf(xpath_tree *xs,
break;
}
break;
+ case XP_NODE: /* s0 is namespace prefix, s1 is name */
+ if (xs->xs_s0)
+ cprintf(xcb, "%s:", xs->xs_s0);
+ cprintf(xcb, "%s", xs->xs_s1);
+ break;
+ case XP_PRIME_NR:
+ cprintf(xcb, "%s", xs->xs_strnr?xs->xs_strnr:"0");
+ break;
+ case XP_PRIME_STR:
+ cprintf(xcb, "'%s'", xs->xs_s0?xs->xs_s0:"");
+ break;
+ case XP_PRIME_FN:
+ if (xs->xs_s0)
+ cprintf(xcb, "%s(", xs->xs_s0);
+ break;
default:
break;
}
if (xs->xs_c0 && xpath_tree2cbuf(xs->xs_c0, xcb) < 0)
goto done;
switch (xs->xs_type){
+ case XP_AND: /* and or */
+ case XP_ADD: /* div mod + * - */
+ case XP_RELEX: /* !=, >= <= < > = */
+ case XP_UNION:
+ if (xs->xs_c1)
+ cprintf(xcb, " %s ", clicon_int2str(xpopmap, xs->xs_int));
+ break;
case XP_RELLOCPATH:
if (xs->xs_c1){
if (xs->xs_int == A_DESCENDANT_OR_SELF)
@@ -293,9 +304,9 @@ xpath_tree2cbuf(xpath_tree *xs,
if (xs->xs_c1)
cprintf(xcb, "[");
break;
- case XP_RELEX:
- if (xs->xs_c1)
- cprintf(xcb, "%s", clicon_int2str(xpopmap, xs->xs_int));
+ case XP_EXP:
+ if (xs->xs_c0 && xs->xs_c1) /* Function name and two arguments, insert , */
+ cprintf(xcb, ",");
break;
default:
break;
@@ -307,6 +318,9 @@ xpath_tree2cbuf(xpath_tree *xs,
if (xs->xs_c1)
cprintf(xcb, "]");
break;
+ case XP_PRIME_FN:
+ if (xs->xs_s0)
+ cprintf(xcb, ")");
default:
break;
}
diff --git a/test/test_netconf_filter.sh b/test/test_netconf_filter.sh
index f20b2b07..73b5e4f6 100755
--- a/test/test_netconf_filter.sh
+++ b/test/test_netconf_filter.sh
@@ -80,6 +80,33 @@ expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^11]]>]]>$"
+new "put more entries"
+expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO31345425675]]>]]>" "^]]>]]>$"
+
+new "netconf commit"
+expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$"
+
+new "get xpath function not b=1"
+expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^2231345425675]]>]]>$"
+
+new "get xpath function not(b)"
+expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^5]]>]]>$"
+
+new "get xpath function contains"
+expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^2242567]]>]]>$"
+
+new "get xpath function not(contains(fib,2))"
+expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^11313455]]>]]>$"
+
+new "get xpath function or"
+expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^3134542567]]>]]>$"
+
+new "get xpath function and"
+expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^11]]>]]>$"
+
+new "get xpath function union"
+expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^115]]>]]>$"
+
if [ $BE -ne 0 ]; then
new "Kill backend"
# Check if premature kill
diff --git a/test/test_restconf.sh b/test/test_restconf.sh
index cb01bb6e..8464d5d5 100755
--- a/test/test_restconf.sh
+++ b/test/test_restconf.sh
@@ -13,7 +13,7 @@
# - IPv6 by default disabled since docker does not support it out-of-the box
# (4) local/backend config. Native only
# - The tests runs through both (if compiled with native)
-# See also test_restconf2.sh
+# See also test_restconf_op.sh
# See test_restconf_rpc.sh for cases when CLICON_BACKEND_RESTCONF_PROCESS is set
# Magic line must be first in script (see README.md)
diff --git a/test/test_xpath_canonical.sh b/test/test_xpath_canonical.sh
index deb05fb0..e541234b 100755
--- a/test/test_xpath_canonical.sh
+++ b/test/test_xpath_canonical.sh
@@ -48,19 +48,19 @@ new "xpath canonical form (other)"
expectpart "$($clixon_util_xpath -c -y $ydir -p /i:x/j:y -n i:urn:example:a -n j:urn:example:b)" 0 '/a:x/b:y' '0 : a = "urn:example:a"' '1 : b = "urn:example:b"'
new "xpath canonical form predicate 1"
-expectpart "$($clixon_util_xpath -c -y $ydir -p "/i:x[j:y='e1']" -n i:urn:example:a -n j:urn:example:b)" 0 "/a:x\[b:y='e1'\]" '0 : a = "urn:example:a"' '1 : b = "urn:example:b"'
+expectpart "$($clixon_util_xpath -c -y $ydir -p "/i:x[j:y='e1']" -n i:urn:example:a -n j:urn:example:b)" 0 "/a:x\[b:y = 'e1'\]" '0 : a = "urn:example:a"' '1 : b = "urn:example:b"'
new "xpath canonical form predicate self"
-expectpart "$($clixon_util_xpath -c -y $ydir -p "/i:x[.='42']" -n i:urn:example:a -n j:urn:example:b)" 0 "/a:x\[.='42'\]" '0 : a = "urn:example:a"'
+expectpart "$($clixon_util_xpath -c -y $ydir -p "/i:x[.='42']" -n i:urn:example:a -n j:urn:example:b)" 0 "/a:x\[. = '42'\]" '0 : a = "urn:example:a"'
new "xpath canonical form descendants"
-expectpart "$($clixon_util_xpath -c -y $ydir -p "//x[.='42']" -n null:urn:example:a -n j:urn:example:b)" 0 "//a:x\[.='42'\]" '0 : a = "urn:example:a"'
+expectpart "$($clixon_util_xpath -c -y $ydir -p "//x[.='42']" -n null:urn:example:a -n j:urn:example:b)" 0 "//a:x\[. = '42'\]" '0 : a = "urn:example:a"'
new "xpath canonical form (no default should fail)"
-expectpart "$($clixon_util_xpath -c -y $ydir -p /x/j:y -n i:urn:example:a -n j:urn:example:b)" 255
+expectpart "$($clixon_util_xpath -c -y $ydir -p /x/j:y -n i:urn:example:a -n j:urn:example:b 2> /dev/null)" 255
new "xpath canonical form (wrong namespace should fail)"
-expectpart "$($clixon_util_xpath -c -y $ydir -p /i:x/j:y -n i:urn:example:c -n j:urn:example:b)" 255
+expectpart "$($clixon_util_xpath -c -y $ydir -p /i:x/j:y -n i:urn:example:c -n j:urn:example:b 2>/dev/null)" 255
rm -rf $dir
diff --git a/test/test_xpath_functions.sh b/test/test_xpath_functions.sh
index 5fd2cc5d..22d91465 100755
--- a/test/test_xpath_functions.sh
+++ b/test/test_xpath_functions.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-# From both:
+# test xpath functions in YANG conditionals
# XPATH base https://www.w3.org/TR/xpath-10/
# YANG XPATH functions: https://tools.ietf.org/html/rfc7950
# Tests: