Closed pprindeville closed 3 months ago
Here is such a function. Unfortunately, it was not possible to use it in other lib functions (such as expand or validation code) due to a more complex context, especially typing, and also more specific error handling. As such it is a utility function, you should be able to use it, but for now I will not add it in the lib.
/*! Given an xml leafref node, return the original node it references
*
* @param[in] xt XML node (LEAF or LEAF-lIST) of type leafref
* @param[out] xref Node that xt references, if any
* @tretval 0 OK, with xref set or not
* @tretval -1 Error
*/
int
xml_get_leafref(cxobj *xt,
yang_stmt *yt,
yang_stmt *ytype,
cxobj **xref)
{
int retval = -1;
char *xt_body;
char *xref_body;
yang_stmt *ypath;
char *path_arg;
cxobj **xvec = NULL;
size_t xlen = 0;
cxobj *x;
int i;
cvec *nsc = NULL;
yang_stmt *yt;
yang_stmt *ytype = NULL;
if ((yt = xml_spec(xt)) == NULL)
goto ok;
if (yang_keyword_get(yt) != Y_LEAF && yang_keyword_get(yt) != Y_LEAF_LIST)
goto ok;
if (yang_type_get(yt, NULL, &ytype, NULL, NULL, NULL, NULL, NULL) < 0)
goto done;
if (ytype == NULL || strcmp(yang_argument_get(ytype), "leafref") != 0)
goto ok;
if (xt == NULL || yt == NULL || ytype == NULL || xref == NULL){
clixon_err(OE_XML, EINVAL, "input parameter is NULL");
goto done;
}
if ((ypath = yang_find(ytype, Y_PATH, NULL)) == NULL)
goto ok;
if ((path_arg = yang_argument_get(ypath)) == NULL)
goto ok;
if (xml_nsctx_yang(yt, &nsc) < 0)
goto done;
if ((xt_body = xml_body(xt)) == NULL)
goto ok;
if (xpath_vec(xt, nsc, "%s", &xvec, &xlen, path_arg) < 0)
goto done;
for (i = 0; i < xlen; i++) {
x = xvec[i];
if ((xref_body = xml_body(x)) == NULL)
continue;
if (strcmp(xt_body, xref_body) == 0){
*xref = x;
break;
}
}
ok:
retval = 0;
done:
if (xvec)
free(xvec);
return retval;
}
If I have a
leafref
type node, I could embed the logic in C toxpath_first()
format it with a hardcoded path, etc. but all of that should be captured into the state of the parsed YANG, and changing the YANG would require changing the C... having a method that indirects the currentcxobj
to its target would be very handy and save much effort.