* Fixed: [when condition error under augment in restconf #227](https://github.com/clicon/clixon/issues/227)
* As part of this fix added custom constant XML_PARENT_CANDIDATE
This commit is contained in:
parent
5b39418e92
commit
1ef7a280d7
8 changed files with 178 additions and 31 deletions
|
|
@ -205,7 +205,7 @@ check_body_namespace(cxobj *x0,
|
|||
|
||||
/*! Check yang when condition between a new xml x1 and old x0
|
||||
*
|
||||
* check if there is a when condition. First try it on the new request (x1), then on the
|
||||
* Check if there is a when condition. First try it on the new request (x1), then on the
|
||||
* existing (x0).
|
||||
* @param[in] x0p Parent of x0
|
||||
* @param[in] x1 XML tree which modifies base
|
||||
|
|
@ -226,9 +226,9 @@ check_when_condition(cxobj *x0p,
|
|||
char *xpath = NULL;
|
||||
cvec *nsc = NULL;
|
||||
int nr;
|
||||
cxobj *x1p;
|
||||
yang_stmt *y = NULL;
|
||||
cbuf *cberr = NULL;
|
||||
cxobj *x1p;
|
||||
|
||||
if ((y = y0) != NULL ||
|
||||
(y = (yang_stmt*)xml_spec(x1)) != NULL){
|
||||
|
|
@ -272,7 +272,7 @@ check_when_condition(cxobj *x0p,
|
|||
* @param[in] h Clicon handle
|
||||
* @param[in] x0 Base xml tree (can be NULL in add scenarios)
|
||||
* @param[in] x0p Parent of x0
|
||||
* @param[in] x0t
|
||||
* @param[in] x0t Top level of existing tree, eg needed for NACM rules
|
||||
* @param[in] x1 XML tree which modifies base
|
||||
* @param[in] x1t Request root node (nacm needs this)
|
||||
* @param[in] y0 Yang spec corresponding to xml-node x0. NULL if x0 is NULL
|
||||
|
|
@ -662,7 +662,9 @@ text_modify(clicon_handle h,
|
|||
if ((x0 = xml_new(x1name, NULL, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
xml_spec_set(x0, y0);
|
||||
|
||||
#ifdef XML_PARENT_CANDIDATE
|
||||
xml_parent_candidate_set(x0, x0p);
|
||||
#endif
|
||||
changed++;
|
||||
/* Get namespace from x1
|
||||
* Check if namespace exists in x0 parent
|
||||
|
|
@ -730,8 +732,8 @@ text_modify(clicon_handle h,
|
|||
x1c = NULL;
|
||||
i = 0;
|
||||
while ((x1c = xml_child_each(x1, x1c, CX_ELMNT)) != NULL) {
|
||||
x1cname = xml_name(x1c);
|
||||
x0c = x0vec[i++];
|
||||
x1cname = xml_name(x1c);
|
||||
yc = yang_find_datanode(y0, x1cname);
|
||||
if ((ret = text_modify(h, x0c, x0, x0t, x1c, x1t,
|
||||
yc, op,
|
||||
|
|
@ -742,6 +744,9 @@ text_modify(clicon_handle h,
|
|||
goto fail;
|
||||
}
|
||||
if (changed){
|
||||
#ifdef XML_PARENT_CANDIDATE
|
||||
xml_parent_candidate_set(x0, NULL);
|
||||
#endif
|
||||
if (xml_insert(x0p, x0, insert, keystr, nscx1) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -786,7 +791,7 @@ text_modify(clicon_handle h,
|
|||
/*! Modify a top-level base tree x0 with modification tree x1
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] x0 Base xml tree (can be NULL in add scenarios)
|
||||
* @param[in] x0t
|
||||
* @param[in] x0t Top level of existing tree, eg needed for NACM rules
|
||||
* @param[in] x1 XML tree which modifies base
|
||||
* @param[in] x1t Request root node (nacm needs this)
|
||||
* @param[in] yspec Top-level yang spec (if y is NULL)
|
||||
|
|
|
|||
|
|
@ -166,6 +166,9 @@ struct xml{
|
|||
char *x_prefix; /* namespace localname N, called prefix */
|
||||
uint16_t x_flags; /* Flags according to XML_FLAG_* */
|
||||
struct xml *x_up; /* parent node in hierarchy if any */
|
||||
#ifdef XML_PARENT_CANDIDATE
|
||||
struct xml *x_up_candidate; /* Candidate parent node for special cases (when+xpath) */
|
||||
#endif
|
||||
int _x_vector_i; /* internal use: xml_child_each */
|
||||
int _x_i; /* internal use for sorting:
|
||||
see xml_enumerate and xml_cmp */
|
||||
|
|
@ -196,6 +199,9 @@ struct xmlbody{
|
|||
char *xb_prefix; /* namespace localname N, called prefix */
|
||||
uint16_t xb_flags; /* Flags according to XML_FLAG_* */
|
||||
struct xml *xb_up; /* parent node in hierarchy if any */
|
||||
#ifdef XML_PARENT_CANDIDATE
|
||||
struct xml *xb_up_candidate; /* Candidate parent node for special cases (when+xpath) */
|
||||
#endif
|
||||
int _xb_vector_i; /* internal use: xml_child_each */
|
||||
int _xb_i; /* internal use for sorting:
|
||||
see xml_enumerate and xml_cmp */
|
||||
|
|
@ -251,6 +257,7 @@ xml_stats_one(cxobj *x,
|
|||
{
|
||||
size_t sz = 0;
|
||||
|
||||
|
||||
if (x->x_name)
|
||||
sz += strlen(x->x_name) + 1;
|
||||
if (x->x_prefix)
|
||||
|
|
@ -587,6 +594,34 @@ xml_parent_set(cxobj *xn,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef XML_PARENT_CANDIDATE
|
||||
/*! Get candidate parent of xnode
|
||||
* @param[in] xn xml node
|
||||
* @retval parent xml node
|
||||
*/
|
||||
cxobj*
|
||||
xml_parent_candidate(cxobj *xn)
|
||||
{
|
||||
if (xn == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return xn->x_up_candidate;
|
||||
}
|
||||
|
||||
/*! Set candidate parent of xml node
|
||||
* @param[in] xn xml node
|
||||
* @param[in] parent pointer to candidate parent xml node
|
||||
* @retval 0 OK
|
||||
*/
|
||||
int
|
||||
xml_parent_candidate_set(cxobj *xn,
|
||||
cxobj *parent)
|
||||
{
|
||||
xn->x_up_candidate = parent;
|
||||
return 0;
|
||||
}
|
||||
#endif /* XML_PARENT_CANDIDATE */
|
||||
|
||||
/*! Get xml node flags, used for internal algorithms
|
||||
* @param[in] xn xml node
|
||||
* @retval flag Flag value(s), see XML_FLAG_MARK et al
|
||||
|
|
@ -1420,8 +1455,7 @@ xml_child_rm(cxobj *xp,
|
|||
* @param[in] xc xml child node to be removed
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @note you should not remove xchild in loop (unless yoy keep track of xprev)
|
||||
*
|
||||
* @note you should not remove xchild in loop (unless you keep track of xprev)
|
||||
* @see xml_child_rm Remove a child of a node
|
||||
*/
|
||||
int
|
||||
|
|
|
|||
|
|
@ -392,7 +392,12 @@ xp_eval_step(xp_ctx *xc0,
|
|||
xc->xc_nodeset = NULL;
|
||||
for (i=0; i<veclen; i++){
|
||||
x = vec[i];
|
||||
if ((xp = xml_parent(x)) != NULL)
|
||||
if ((xp = xml_parent(x)) != NULL
|
||||
#ifdef XML_PARENT_CANDIDATE
|
||||
/* Also check "candidate" parent for special when use-case */
|
||||
|| (xp = xml_parent_candidate(x)) != NULL
|
||||
#endif /* XML_PARENT_CANDIDATE */
|
||||
)
|
||||
if (cxvec_append(xp, &xc->xc_nodeset, &xc->xc_size) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -979,8 +984,13 @@ xp_eval(xp_ctx *xc,
|
|||
case XP_ABSPATH:
|
||||
/* Set context node to top node, and nodeset to that node only */
|
||||
x = xc->xc_node;
|
||||
#ifdef XML_PARENT_CANDIDATE
|
||||
while (xml_parent(x) != NULL || xml_parent_candidate(x) != NULL)
|
||||
x = xml_parent(x)?xml_parent(x):xml_parent_candidate(x);
|
||||
#else
|
||||
while (xml_parent(x) != NULL)
|
||||
x = xml_parent(x);
|
||||
#endif
|
||||
xc->xc_node = x;
|
||||
xc->xc_nodeset[0] = x;
|
||||
xc->xc_size=1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue