* Added XPATH functions position

This commit is contained in:
Olof hagsand 2020-10-27 09:40:45 +01:00
parent 8f81eb1c66
commit fab261cb53
13 changed files with 98 additions and 23 deletions

View file

@ -274,7 +274,7 @@ netconf_missing_attribute(cbuf *cb,
* out of range, pattern mismatch.
* @param[out] cb CLIgen buf. Error XML is written in this buffer
* @param[in] type Error type: "rpc", "application" or "protocol"
* @param[in] info bad-attribute or bad-element xml
* @param[in] info Attribute name
* @param[in] message Error message (will be XML encoded)
*/
int
@ -303,7 +303,7 @@ netconf_bad_attribute(cbuf *cb,
* out of range, pattern mismatch.
* @param[out] xret Error XML tree. Free with xml_free after use
* @param[in] type Error type: "rpc", "application" or "protocol"
* @param[in] info bad-attribute or bad-element xml
* @param[in] info Attribute name
* @param[in] message Error message (will be XML encoded)
*/
int
@ -331,7 +331,7 @@ netconf_bad_attribute_xml(cxobj **xret,
goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-type>%s</error-type>"
"<error-tag>bad-attribute</error-tag>"
"<error-info>%s</error-info>"
"<error-info><bad-attribute>%s</bad-attribute></error-info>"
"<error-severity>error</error-severity>", type, info) < 0)
goto done;
if (message){
@ -348,7 +348,6 @@ netconf_bad_attribute_xml(cxobj **xret,
return retval;
}
/*! Create Netconf unknown-attribute error XML tree according to RFC 6241 App A
*
* An unexpected attribute is present.

View file

@ -494,6 +494,7 @@ xp_eval_predicate(xp_ctx *xc,
xcc->xc_type = XT_NODESET;
xcc->xc_initial = xc->xc_initial;
xcc->xc_node = x;
xcc->xc_position = i;
/* For each node in the node-set to be filtered, the PredicateExpr is
* evaluated with that node as the context node */
if (cxvec_append(x, &xcc->xc_nodeset, &xcc->xc_size) < 0)
@ -746,12 +747,35 @@ xp_relop(xp_ctx *xc1,
xr->xc_bool = (xc1->xc_bool == xc2->xc_bool);
break;
case XT_NUMBER:
xr->xc_bool = (xc1->xc_number == xc2->xc_number);
switch(op){
case XO_EQ:
xr->xc_bool = (xc1->xc_number == xc2->xc_number);
break;
case XO_NE:
xr->xc_bool = (xc1->xc_number != xc2->xc_number);
break;
case XO_GE:
xr->xc_bool = (xc1->xc_number >= xc2->xc_number);
break;
case XO_LE:
xr->xc_bool = (xc1->xc_number <= xc2->xc_number);
break;
case XO_LT:
xr->xc_bool = (xc1->xc_number < xc2->xc_number);
break;
case XO_GT:
xr->xc_bool = (xc1->xc_number > xc2->xc_number);
break;
default:
clicon_err(OE_XML, 0, "Operator %s not supported for nodeset/nodeset comparison", clicon_int2str(xpopmap,op));
goto done;
break;
}
break;
case XT_STRING:
xr->xc_bool = (strcmp(xc1->xc_string, xc2->xc_string)==0);
break;
}
} /* switch xc1 */
}
else if (xc1->xc_type != XT_NODESET &&
xc2->xc_type != XT_NODESET){
@ -991,6 +1015,11 @@ xp_eval(xp_ctx *xc,
goto done;
goto ok;
break;
case XPATHFN_POSITION:
if (xp_function_position(xc, xs->xs_c0, nsc, localonly, xrp) < 0)
goto done;
goto ok;
break;
case XPATHFN_COUNT:
if (xp_function_count(xc, xs->xs_c0, nsc, localonly, xrp) < 0)
goto done;

View file

@ -376,6 +376,41 @@ xp_function_derived_from(xp_ctx *xc,
return retval;
}
/*! Return a number equal to the context position from the expression evaluation context.
*
* Signature: number position(node-set)
* @param[in] xc0 Incoming context
* @param[in] xs XPATH node tree
* @param[in] nsc XML Namespace context
* @param[in] localonly Skip prefix and namespace tests (non-standard)
* @param[out] xrp Resulting context
* @retval 0 OK
* @retval -1 Error
*/
int
xp_function_position(xp_ctx *xc0,
struct xpath_tree *xs,
cvec *nsc,
int localonly,
xp_ctx **xrp)
{
int retval = -1;
xp_ctx *xr = NULL;
if ((xr = malloc(sizeof(*xr))) == NULL){
clicon_err(OE_UNIX, errno, "malloc");
goto done;
}
memset(xr, 0, sizeof(*xr));
xr->xc_initial = xc0->xc_initial;
xr->xc_type = XT_NUMBER;
xr->xc_number = xc0->xc_position;
*xrp = xr;
retval = 0;
done:
return retval;
}
/*! The count function returns the number of nodes in the argument node-set.
*
* Signature: number count(node-set)
@ -527,7 +562,7 @@ xp_function_contains(xp_ctx *xc,
/*! The not function returns true if its argument is false, and false otherwise.
*
* Signatire: boolean contains(boolean)
* Signature: boolean not(boolean)
*/
int
xp_function_not(xp_ctx *xc0,

View file

@ -55,7 +55,7 @@ enum clixon_xpath_function{
XPATHFN_ENUM_VALUE, /* RFC 7950 10.5.1 NYI */
XPATHFN_BIT_IS_SET, /* RFC 7950 10.6.1 NYI */
XPATHFN_LAST, /* XPATH 1.0 4.1 NYI */
XPATHFN_POSITION, /* XPATH 1.0 4.1 NYI */
XPATHFN_POSITION, /* XPATH 1.0 4.1 */
XPATHFN_COUNT, /* XPATH 1.0 4.1 */
XPATHFN_ID, /* XPATH 1.0 4.1 NYI */
XPATHFN_LOCAL_NAME, /* XPATH 1.0 4.1 NYI */
@ -96,6 +96,7 @@ const char *xp_fnname_int2str(enum clixon_xpath_function code);
int xp_function_current(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
int xp_function_deref(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
int xp_function_derived_from(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, int self, xp_ctx **xrp);
int xp_function_position(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
int xp_function_count(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
int xp_function_name(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
int xp_function_contains(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);

View file

@ -235,7 +235,6 @@ xp_primary_function(clixon_xpath_yacc *xpy,
case XPATHFN_ENUM_VALUE:
case XPATHFN_BIT_IS_SET:
case XPATHFN_LAST:
case XPATHFN_POSITION:
case XPATHFN_ID:
case XPATHFN_LOCAL_NAME:
case XPATHFN_NAMESPACE_URI:
@ -269,6 +268,7 @@ xp_primary_function(clixon_xpath_yacc *xpy,
case XPATHFN_DEREF:
case XPATHFN_DERIVED_FROM:
case XPATHFN_DERIVED_FROM_OR_SELF:
case XPATHFN_POSITION:
case XPATHFN_COUNT:
case XPATHFN_NAME:
case XPATHFN_CONTAINS: