* Much better support for XPATH 1.0 according to https://www.w3.org/TR/xpath-10 using yacc/lex

* NOTE: Due to an error in the previous implementation, all XPATH calls on the form `x[a=str]` where `str` is a string (not a number or XML symbol), must be changed to: `x[a='str'] or x[a="str"]`
    * This includes all calls to `xpath_vec, xpath_first`, etc.
    * All calls to cli_copy_config in CLI spec files must replace 2nd argument from `x[%s=%s]` to `x[%s='%s']`
  * The old API is stillenabled. To define the new, define XPATH_USE_NEW in include/clixon_custom.h and recompile
This commit is contained in:
Olof hagsand 2018-07-17 16:59:32 +02:00
parent 5d7c4a8d18
commit ba7f84afee
29 changed files with 395 additions and 79 deletions

View file

@ -83,6 +83,8 @@
#include "clixon_options.h"
#include "clixon_xml.h"
#include "clixon_plugin.h"
#include "clixon_xpath_ctx.h"
#include "clixon_xpath.h"
#include "clixon_xsl.h"
#include "clixon_log.h"
#include "clixon_err.h"
@ -439,7 +441,7 @@ xml_yang_validate_all(cxobj *xt,
case Y_LEAF_LIST:
/* Special case if leaf is leafref, then first check against
current xml tree
*/
*/
if ((yc = yang_find((yang_node*)ys, Y_TYPE, NULL)) != NULL){
if (strcmp(yc->ys_argument, "leafref") == 0){
if (validate_leafref(xt, yc) < 0)
@ -995,7 +997,7 @@ api_path_fmt2api_path(char *api_path_fmt,
* @example
* api_path_fmt: /interface/%s/address/%s
* cvv: name=eth0
* xpath: /interface/[name=eth0]/address
* xpath: /interface/[name='eth0']/address
* @example
* api_path_fmt: /ip/me/%s (if key)
* cvv: -
@ -1038,7 +1040,13 @@ api_path_fmt2xpath(char *api_path_fmt,
clicon_err(OE_UNIX, errno, "cv2str_dup");
goto done;
}
cprintf(cb, "[%s=%s]", cv_name_get(cv), str);
cprintf(cb,
#ifdef XPATH_USE_NEW
"[%s='%s']",
#else
"[%s=%s]",
#endif
cv_name_get(cv), str);
free(str);
}
}
@ -1455,7 +1463,13 @@ api_path2xpath_cvv(yang_spec *yspec,
cprintf(xpath, "/%s", name);
v = val;
while ((cvi = cvec_each(cvk, cvi)) != NULL){
cprintf(xpath, "[%s=%s]", cv_string_get(cvi), v);
cprintf(xpath,
#ifdef XPATH_USE_NEW
"[%s='%s']",
#else
"[%s=%s]",
#endif
cv_string_get(cvi), v);
v += strlen(v)+1;
}
if (val)