Creator attribute changes: added as xmldb metadata
clixon-config.yang: New revision and Added `CLICON_NETCONF_CREATOR_ATTR` option clixon-lib.yang: Added creator meta Changed return value of xml_add_attr
This commit is contained in:
parent
be3001acf5
commit
bbcb4a7b03
20 changed files with 474 additions and 93 deletions
|
|
@ -442,6 +442,56 @@ disable_nacm_on_empty(cxobj *xt,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Read creator data from meta-data and add to xml internal annotation
|
||||
*
|
||||
* Iterate creator meta-data using xpaths and create internal creator annotations
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] xt XML top node
|
||||
* @param[in] xn XML creators node
|
||||
* On the form:
|
||||
* <creator>
|
||||
* <name>testA[name='foo']</name>
|
||||
* <xpath>...</xpath>
|
||||
* ...
|
||||
* </creator>
|
||||
* @see xml_creator_metadata_write
|
||||
*/
|
||||
static int
|
||||
xml_creator_metadata_read(clicon_handle h,
|
||||
cxobj *xn)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xt;
|
||||
cxobj *xc;
|
||||
cxobj *xp;
|
||||
cxobj *x;
|
||||
char *name;
|
||||
char *xpath;
|
||||
|
||||
xt = xml_root(xn);
|
||||
xc = NULL;
|
||||
while ((xc = xml_child_each(xn, xc, CX_ELMNT)) != NULL) {
|
||||
if (strcmp(xml_name(xc), "creator"))
|
||||
continue;
|
||||
if ((name = xml_find_body(xc, "name")) == NULL)
|
||||
continue;
|
||||
xp = NULL;
|
||||
while ((xp = xml_child_each(xc, xp, CX_ELMNT)) != NULL) {
|
||||
if (strcmp(xml_name(xp), "path"))
|
||||
continue;
|
||||
if ((xpath = xml_body(xp)) == NULL)
|
||||
continue;
|
||||
if ((x = xpath_first(xt, NULL, "%s", xpath)) == NULL)
|
||||
continue;
|
||||
if (xml_creator_add(x, name) < 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Common read function that reads an XML tree from file
|
||||
*
|
||||
* @param[in] th Datastore text handle
|
||||
|
|
@ -543,7 +593,19 @@ xmldb_readfile(clicon_handle h,
|
|||
xml_flag_set(x0, XML_FLAG_TOP);
|
||||
if (xml_child_nr(x0) == 0 && de)
|
||||
de->de_empty = 1;
|
||||
|
||||
/* Check if creator attributes are supported*/
|
||||
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR")){
|
||||
if ((x = xpath_first(x0, NULL, "creators")) != NULL){
|
||||
ns = NULL;
|
||||
if (xml2ns(x, NULL, &ns) < 0)
|
||||
goto done;
|
||||
if (strcmp(ns, CLIXON_LIB_NS) == 0){
|
||||
if (xml_creator_metadata_read(h, x) < 0)
|
||||
goto done;
|
||||
xml_purge(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check if we support modstate */
|
||||
if (clicon_option_bool(h, "CLICON_XMLDB_MODSTATE"))
|
||||
if ((msdiff = modstate_diff_new()) == NULL)
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@
|
|||
* An attribute may have a prefix(or NULL). The routine finds the associated
|
||||
* xmlns binding to find the namespace: <namespace>:<name>.
|
||||
* If such an attribute is not found, failure is returned with cbret set,
|
||||
* If such an attribute its found, its string value is returned.
|
||||
* If such an attribute is found, its string value is returned and removed from XML
|
||||
* @param[in] x XML node (where to look for attribute)
|
||||
* @param[in] name Attribute name
|
||||
* @param[in] ns (Expected) Namespace of attribute
|
||||
|
|
@ -98,6 +98,7 @@
|
|||
* @retval 1 OK
|
||||
* @retval 0 Failed (cbret set)
|
||||
* @retval -1 Error
|
||||
* @note as a side.effect the attribute is removed
|
||||
*/
|
||||
static int
|
||||
attr_ns_value(cxobj *x,
|
||||
|
|
@ -142,6 +143,70 @@ attr_ns_value(cxobj *x,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*! Add creator data to metadata xml object on the form name:xpath*
|
||||
*
|
||||
* Callback function type for xml_apply
|
||||
* @param[in] x XML node
|
||||
* @param[in] arg General-purpose argument
|
||||
* @retval -1 Error, aborted at first error encounter, return -1 to end user
|
||||
* @retval 0 OK, continue
|
||||
* @retval 1 Abort, dont continue with others, return 1 to end user
|
||||
* @retval 2 Locally abort this subtree, continue with others
|
||||
* On the form:
|
||||
* <creator>
|
||||
* <name>testA[name='foo']</name>
|
||||
* <xpath>...</xpath>
|
||||
* ...
|
||||
* </creator>
|
||||
* @see xml_creator_metadata_read
|
||||
*/
|
||||
static int
|
||||
xml_creator_metadata_write(cxobj *x,
|
||||
void *arg)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xmeta = (cxobj*)arg;
|
||||
cxobj *xmc;
|
||||
cvec *cvv;
|
||||
cg_var *cv;
|
||||
char *val;
|
||||
cvec *nsc = NULL;
|
||||
char *xpath = NULL;
|
||||
|
||||
if ((cvv = xml_creator_get(x)) == NULL){
|
||||
retval = 0;
|
||||
goto done;
|
||||
}
|
||||
/* Note this requires x to have YANG spec */
|
||||
if (xml2xpath(x, nsc, 0, 0, &xpath) < 0)
|
||||
goto done;
|
||||
cv = NULL;
|
||||
while ((cv = cvec_each(cvv, cv)) != NULL){
|
||||
val = cv_name_get(cv);
|
||||
/* Find existing entry where name is val */
|
||||
xmc = NULL;
|
||||
while ((xmc = xml_child_each(xmeta, xmc, CX_ELMNT)) != NULL){
|
||||
if (strcmp(xml_find_body(xmc, "name"), val) == 0)
|
||||
break;
|
||||
}
|
||||
if (xmc != NULL){
|
||||
if (clixon_xml_parse_va(YB_NONE, NULL, &xmc, NULL, "<path>%s</path>", xpath) < 0)
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
if (clixon_xml_parse_va(YB_NONE, NULL, &xmeta, NULL,
|
||||
"<creator><name>%s</name><path>%s</path></creator>",
|
||||
val, xpath) < 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 2;
|
||||
done:
|
||||
if (xpath)
|
||||
free(xpath);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! When new body is added, some needs type lookup is made and namespace checked
|
||||
*
|
||||
* This includes identityrefs, paths
|
||||
|
|
@ -209,11 +274,11 @@ check_body_namespace(cxobj *x0,
|
|||
goto done;
|
||||
/* Create xmlns attribute to x0 XXX same code ^*/
|
||||
if (prefix){
|
||||
if (xml_add_attr(x, prefix, ns0, "xmlns", NULL) < 0)
|
||||
if (xml_add_attr(x, prefix, ns0, "xmlns", NULL) == NULL)
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
if (xml_add_attr(x, "xmlns", ns0, NULL, NULL) < 0)
|
||||
if (xml_add_attr(x, "xmlns", ns0, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
xml_sort(x); /* Ensure attr is first / XXX xml_insert? */
|
||||
}
|
||||
|
|
@ -231,7 +296,7 @@ check_body_namespace(cxobj *x0,
|
|||
;
|
||||
}
|
||||
else{ /* Add it according to the kludge,... */
|
||||
if (xml_add_attr(x0, prefix, ns0, "xmlns", NULL) < 0)
|
||||
if (xml_add_attr(x0, prefix, ns0, "xmlns", NULL) == NULL)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
|
@ -513,7 +578,6 @@ text_modify(clicon_handle h,
|
|||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
|
||||
if (createstr != NULL &&
|
||||
(op == OP_REPLACE || op == OP_MERGE || op == OP_CREATE)){
|
||||
if (x0 == NULL || xml_defaults_nopresence(x0, 0)){ /* does not exist or is default */
|
||||
|
|
@ -532,11 +596,13 @@ text_modify(clicon_handle h,
|
|||
clicon_data_set(h, "objectexisted", "true");
|
||||
}
|
||||
}
|
||||
/* Special clixon-lib attribute for keeping track of creator of objects */
|
||||
if ((ret = attr_ns_value(x1, "creator", CLIXON_LIB_NS, cbret, &creator)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR")){
|
||||
/* Special clixon-lib attribute for keeping track of creator of objects */
|
||||
if ((ret = attr_ns_value(x1, "creator", CLIXON_LIB_NS, cbret, &creator)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
x1name = xml_name(x1);
|
||||
|
||||
if (yang_keyword_get(y0) == Y_LEAF_LIST ||
|
||||
|
|
@ -798,12 +864,13 @@ text_modify(clicon_handle h,
|
|||
}
|
||||
/* XXX: Note, if there is an error in adding the object later, the
|
||||
* original object is not reverted.
|
||||
* XXX: Here creator attributes in x0 are destroyed
|
||||
*/
|
||||
if (x0){
|
||||
/* Recursively copy creator attributes from existing tree */
|
||||
if (xml_creator_copy_all(x0, x1) < 0)
|
||||
goto done;
|
||||
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR")){
|
||||
/* Recursively copy creator attributes from existing tree */
|
||||
if (xml_creator_copy_all(x0, x1) < 0)
|
||||
goto done;
|
||||
}
|
||||
xml_purge(x0);
|
||||
x0 = NULL;
|
||||
}
|
||||
|
|
@ -854,8 +921,10 @@ text_modify(clicon_handle h,
|
|||
#ifdef XML_PARENT_CANDIDATE
|
||||
xml_parent_candidate_set(x0, x0p);
|
||||
#endif
|
||||
if (xml_creator_copy_one(x1, x0) < 0)
|
||||
goto done;
|
||||
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR")){
|
||||
if (xml_creator_copy_one(x1, x0) < 0)
|
||||
goto done;
|
||||
}
|
||||
changed++;
|
||||
/* Get namespace from x1
|
||||
* Check if namespace exists in x0 parent
|
||||
|
|
@ -1229,6 +1298,7 @@ xmldb_put(clicon_handle h,
|
|||
int firsttime = 0;
|
||||
int pretty;
|
||||
cxobj *xerr = NULL;
|
||||
cxobj *xmeta = NULL;
|
||||
|
||||
if (cbret == NULL){
|
||||
clicon_err(OE_XML, EINVAL, "cbret is NULL");
|
||||
|
|
@ -1262,6 +1332,16 @@ xmldb_put(clicon_handle h,
|
|||
xml_name(x0), DATASTORE_TOP_SYMBOL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* XXX Ad-hoc:
|
||||
* In yang mounts yang specs may not be available
|
||||
* in initial parsing, but may be at a later stage.
|
||||
* But it should be possible to find a more precise triggering
|
||||
*/
|
||||
if (clicon_option_bool(h, "CLICON_YANG_SCHEMA_MOUNT")){
|
||||
if ((ret = xml_bind_yang(h, x0, YB_MODULE, yspec, NULL)) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* Here x0 looks like: <config>...</config> */
|
||||
#if 0 /* debug */
|
||||
if (xml_apply0(x1, -1, xml_sort_verify, NULL) < 0)
|
||||
|
|
@ -1301,7 +1381,6 @@ xmldb_put(clicon_handle h,
|
|||
if (xml_apply0(x0, -1, xml_sort_verify, NULL) < 0)
|
||||
clicon_log(LOG_NOTICE, "%s: verify failed #3", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
/* Write back to datastore cache if first time */
|
||||
if (clicon_datastore_cache(h) != DATASTORE_NOCACHE){
|
||||
db_elmnt de0 = {0,};
|
||||
|
|
@ -1336,6 +1415,19 @@ xmldb_put(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
pretty = clicon_option_bool(h, "CLICON_XMLDB_PRETTY");
|
||||
/* Add creator attribute */
|
||||
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR")){
|
||||
if ((xmeta = xml_new("creators", x0, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
if (xmlns_set(xmeta, NULL, CLIXON_LIB_NS) < 0)
|
||||
goto done;
|
||||
if (xml_apply(x0, CX_ELMNT, xml_creator_metadata_write, xmeta) < 0)
|
||||
goto done;
|
||||
if (xml_child_nr_type(xmeta, CX_ELMNT) == 0){
|
||||
xml_purge(xmeta);
|
||||
xmeta = NULL;
|
||||
}
|
||||
}
|
||||
if (strcmp(format,"json")==0){
|
||||
if (clixon_json2file(f, x0, pretty, fprintf, 0, 0) < 0)
|
||||
goto done;
|
||||
|
|
@ -1346,6 +1438,10 @@ xmldb_put(clicon_handle h,
|
|||
*/
|
||||
if (xmodst && xml_purge(xmodst) < 0)
|
||||
goto done;
|
||||
if (clicon_option_bool(h, "CLICON_NETCONF_CREATOR_ATTR") && xmeta){
|
||||
if (xml_purge(xmeta) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 1;
|
||||
done:
|
||||
if (f != NULL)
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ json2xml_decode_identityref(cxobj *x,
|
|||
if (prefix2 == NULL)
|
||||
prefix2 = yang_find_myprefix(ymod);
|
||||
/* Add "xmlns:prefix2=namespace" */
|
||||
if (xml_add_attr(x, prefix2, ns, "xmlns", NULL) < 0)
|
||||
if (xml_add_attr(x, prefix2, ns, "xmlns", NULL) == NULL)
|
||||
goto done;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ netconf_invalid_value_xml(cxobj **xret,
|
|||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -302,7 +302,7 @@ netconf_missing_attribute_xml(cxobj **xret,
|
|||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -418,7 +418,7 @@ netconf_bad_attribute_xml(cxobj **xret,
|
|||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -514,7 +514,7 @@ netconf_common_xml(cxobj **xret,
|
|||
if (*xret == NULL){
|
||||
if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
|
|
@ -789,7 +789,7 @@ netconf_access_denied_xml(cxobj **xret,
|
|||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -1034,7 +1034,7 @@ netconf_data_missing_xml(cxobj **xret,
|
|||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -1093,7 +1093,7 @@ netconf_missing_choice_xml(cxobj **xret,
|
|||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -1167,7 +1167,7 @@ netconf_operation_not_supported_xml(cxobj **xret,
|
|||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -1285,7 +1285,7 @@ netconf_operation_failed_xml(cxobj **xret,
|
|||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -1374,7 +1374,7 @@ netconf_malformed_message_xml(cxobj **xret,
|
|||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -1460,7 +1460,7 @@ netconf_data_not_unique_xml(cxobj **xret,
|
|||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -1531,7 +1531,7 @@ netconf_minmax_elements_xml(cxobj **xret,
|
|||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) < 0)
|
||||
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -185,7 +185,8 @@ struct xml{
|
|||
yang_stmt *x_spec; /* Pointer to specification, eg yang,
|
||||
by reference, dont free */
|
||||
cg_var *x_cv; /* Cached value as cligen variable (set by xml_cmp) */
|
||||
cvec *x_creators; /* Support clixon-lib creator annotation */
|
||||
cvec *x_creators; /* Support clixon-lib creator annotation.
|
||||
Only if CLICON_NETCONF_CREATOR_ATTR = true */
|
||||
#ifdef XML_EXPLICIT_INDEX
|
||||
struct search_index *x_search_index; /* explicit search index vectors */
|
||||
#endif
|
||||
|
|
@ -653,7 +654,7 @@ xml_creator_add(cxobj *xn,
|
|||
cg_var *cv;
|
||||
|
||||
if (!is_element(xn))
|
||||
return 0;
|
||||
goto ok;
|
||||
if (xn->x_creators == NULL){
|
||||
if ((xn->x_creators = cvec_new(0)) == NULL){
|
||||
clicon_err(OE_XML, errno, "cvec_new");
|
||||
|
|
@ -662,6 +663,7 @@ xml_creator_add(cxobj *xn,
|
|||
}
|
||||
if ((cv = cvec_find(xn->x_creators, name)) == NULL)
|
||||
cvec_add_string(xn->x_creators, name, NULL);
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
|
|
@ -723,6 +725,16 @@ xml_creator_len(cxobj *xn)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*! Get all creator attributes
|
||||
*/
|
||||
cvec*
|
||||
xml_creator_get(cxobj *xn)
|
||||
{
|
||||
if (!is_element(xn))
|
||||
return 0;
|
||||
return xn->x_creators;
|
||||
}
|
||||
|
||||
/*! Copy creator info from x0 to x1 single object
|
||||
*
|
||||
* @param[in] x0 Source XML node
|
||||
|
|
@ -830,7 +842,7 @@ creator_print_fn(cxobj *x,
|
|||
return 2; /* Locally abort this subtree, continue with others */
|
||||
}
|
||||
|
||||
/*! Print XML and creator tags where they exists, for debugging
|
||||
/*! Print XML and creator tags where they exists recursively, for debugging
|
||||
*
|
||||
* @param[in] xn XML tree
|
||||
* @retval see xml_apply
|
||||
|
|
@ -1355,7 +1367,7 @@ clixon_child_xvec_append(cxobj *xn,
|
|||
* xml_free(x);
|
||||
* @endcode
|
||||
* @note Differentiates between body/attribute vs element to reduce mem allocation
|
||||
* @see xml_sort_insert
|
||||
* @see xml_insert
|
||||
*/
|
||||
cxobj *
|
||||
xml_new(char *name,
|
||||
|
|
@ -2021,10 +2033,10 @@ xml_find_type_value(cxobj *xt,
|
|||
* @see xml_find_value where a body can be found as well
|
||||
*/
|
||||
cxobj *
|
||||
xml_find_type(cxobj *xt,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
enum cxobj_type type)
|
||||
xml_find_type(cxobj *xt,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
enum cxobj_type type)
|
||||
{
|
||||
cxobj *x = NULL;
|
||||
int pmatch; /* prefix match */
|
||||
|
|
@ -2649,18 +2661,17 @@ xml_attr_insert2val(char *instr,
|
|||
* @param[in] value Attribute value
|
||||
* @param[in] prefix Attribute prefix, or NULL
|
||||
* @param[in] namespace Attribute prefix, if NULL do not add namespace mapping
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @retval xa Created attribute object
|
||||
* @retval NULL Error
|
||||
*/
|
||||
int
|
||||
cxobj *
|
||||
xml_add_attr(cxobj *xn,
|
||||
char *name,
|
||||
char *value,
|
||||
char *prefix,
|
||||
char *namespace)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xa;
|
||||
cxobj *xa = NULL;
|
||||
char *ns = NULL;
|
||||
|
||||
if ((xa = xml_new(name, xn, CX_ATTR)) == NULL)
|
||||
|
|
@ -2675,9 +2686,16 @@ xml_add_attr(cxobj *xn,
|
|||
if (ns == NULL && xmlns_set(xn, prefix, namespace) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
if (xml_sort(xn) < 0)
|
||||
goto done;
|
||||
ret:
|
||||
return xa;
|
||||
done:
|
||||
return retval;
|
||||
if (xa){
|
||||
xml_free(xa);
|
||||
xa = NULL;
|
||||
}
|
||||
goto ret;
|
||||
}
|
||||
|
||||
/*! Specialization of clicon_log with xml tree
|
||||
|
|
|
|||
|
|
@ -227,8 +227,13 @@ populate_self_parent(cxobj *xt,
|
|||
}
|
||||
/* Assign spec only if namespaces match */
|
||||
if (strcmp(ns, nsy) != 0){
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cb, "Namespace mismatch: %s in XML does not match %s in yang", ns, nsy);
|
||||
if (xerr &&
|
||||
netconf_bad_element_xml(xerr, "application", name, "Namespace mismatch") < 0)
|
||||
netconf_bad_element_xml(xerr, "application", name, cbuf_get(cb)) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -615,7 +615,7 @@ xml_add_default_tag(cxobj *x,
|
|||
|
||||
if (xml_flag(x, flags)) {
|
||||
/* set default attribute */
|
||||
if (xml_add_attr(x, "default", "true", IETF_NETCONF_WITH_DEFAULTS_ATTR_PREFIX, NULL) < 0)
|
||||
if (xml_add_attr(x, "default", "true", IETF_NETCONF_WITH_DEFAULTS_ATTR_PREFIX, NULL) == NULL)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
|
|
|
|||
|
|
@ -358,12 +358,14 @@ xml_parse_attr(clixon_xml_yacc *xy,
|
|||
int retval = -1;
|
||||
cxobj *xa = NULL;
|
||||
|
||||
/* XXX: here duplicates of same attributes are removed
|
||||
* This is probably not according standard?
|
||||
*/
|
||||
if ((xa = xml_find_type(xy->xy_xelement, prefix, name, CX_ATTR)) == NULL){
|
||||
if ((xa = xml_new(name, xy->xy_xelement, CX_ATTR)) == NULL)
|
||||
goto done;
|
||||
if (xml_prefix_set(xa, prefix) < 0)
|
||||
goto done;
|
||||
|
||||
}
|
||||
if (xml_value_set(xa, attval) < 0)
|
||||
goto done;
|
||||
|
|
@ -484,12 +486,14 @@ pi : BQMARK NAME EQMARK {_PARSE_DEBUG("pi -> <? NAME ?>"); free($2); }
|
|||
;
|
||||
|
||||
|
||||
attrs : attrs attr
|
||||
|
|
||||
attrs : attrs attr { _PARSE_DEBUG("attrs -> attrs attr"); }
|
||||
| { _PARSE_DEBUG("attrs ->"); }
|
||||
;
|
||||
|
||||
attr : NAME '=' attvalue { if (xml_parse_attr(_XY, NULL, $1, $3) < 0) YYABORT; }
|
||||
| NAME ':' NAME '=' attvalue { if (xml_parse_attr(_XY, $1, $3, $5) < 0) YYABORT; }
|
||||
attr : NAME '=' attvalue { if (xml_parse_attr(_XY, NULL, $1, $3) < 0) YYABORT;
|
||||
_PARSE_DEBUG("attr -> NAME = attvalue"); }
|
||||
| NAME ':' NAME '=' attvalue { if (xml_parse_attr(_XY, $1, $3, $5) < 0) YYABORT;
|
||||
_PARSE_DEBUG("attr -> NAME : NAME = attvalue"); }
|
||||
;
|
||||
|
||||
attvalue : '\"' STRING '\"' { $$=$2; /* $2 must be consumed */}
|
||||
|
|
|
|||
|
|
@ -1057,7 +1057,7 @@ xml_insert2(cxobj *xp,
|
|||
/*! Insert xc as child to xp in sorted place. Remove xc from previous parent.
|
||||
*
|
||||
* @param[in] xp Parent xml node. If NULL just remove from old parent.
|
||||
* @param[in] x Child xml node to insert under xp
|
||||
* @param[in] xi Child xml node to insert under xp
|
||||
* @param[in] ins Insert operation (if ordered-by user)
|
||||
* @param[in] key_val Key if x is LIST and ins is before/after, val if LEAF_LIST
|
||||
* @param[in] nsc_key Network namespace for key
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue