* Strict namespace setting can be a problem when upgrading existing database files, such as startup-db or persistent running-db, or any other saved XML file.
* For backward compatibility, load of startup and running set CLICON_XML_NS_STRICT to false temporarily. * Added three-valued return values for several validate functions where -1 is fatal error, 0 is validation failed and 1 is validation OK. * This includes: `xmldb_put`, `xml_yang_validate_all`, `xml_yang_validate_add`, `xml_yang_validate_rpc`, `api_path2xml`, `api_path2xpath` * Added new xml functions for specific types: `xml_child_nr_notype`, `xml_child_nr_notype`, `xml_child_i_type`, `xml_find_type`.
This commit is contained in:
parent
861300d6c0
commit
0baebc93fd
71 changed files with 2679 additions and 1573 deletions
|
|
@ -62,6 +62,8 @@
|
|||
#include "clixon_log.h"
|
||||
#include "clixon_yang.h"
|
||||
#include "clixon_xml.h"
|
||||
#include "clixon_options.h" /* xml_spec_populate */
|
||||
#include "clixon_xml_map.h" /* xml_spec_populate */
|
||||
#include "clixon_xml_sort.h"
|
||||
#include "clixon_xml_parse.h"
|
||||
|
||||
|
|
@ -133,9 +135,9 @@ struct xml{
|
|||
* or rpc if no xmlns attribute specifies namespace.
|
||||
* This is loose semantics of finding namespaces.
|
||||
* And it is wrong, but is the way Clixon originally was written."
|
||||
* @see CLICON_XML_NS_ITERATE clixon configure option
|
||||
* @see CLICON_XML_NS_STRICT clixon configure option
|
||||
*/
|
||||
int _CLICON_XML_NS_ITERATE = 0;
|
||||
int _CLICON_XML_NS_STRICT = 1;
|
||||
|
||||
/* Mapping between xml type <--> string */
|
||||
static const map_str2int xsmap[] = {
|
||||
|
|
@ -226,8 +228,7 @@ xml_prefix_set(cxobj *xn,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*! Given an xml tree return URI namespace: default or localname given
|
||||
/*! Given an xml tree return URI namespace recursively : default or localname given
|
||||
*
|
||||
* Given an XML tree and a prefix (or NULL) return URI namespace.
|
||||
* @param[in] x XML tree
|
||||
|
|
@ -235,7 +236,7 @@ xml_prefix_set(cxobj *xn,
|
|||
* @param[out] namespace URI namespace (or NULL). Note pointer into xml tree
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see xmlns_check XXX coordinate
|
||||
* @see xmlns_check XXX can these be merged?
|
||||
*/
|
||||
int
|
||||
xml2ns(cxobj *x,
|
||||
|
|
@ -246,9 +247,9 @@ xml2ns(cxobj *x,
|
|||
char *ns;
|
||||
cxobj *xp;
|
||||
|
||||
if (prefix != NULL) /* xmlns:<prefix> */
|
||||
if (prefix != NULL) /* xmlns:<prefix>="<uri>" */
|
||||
ns = xml_find_type_value(x, "xmlns", prefix, CX_ATTR);
|
||||
else /* default ns */
|
||||
else /* xmlns="<uri>" */
|
||||
ns = xml_find_type_value(x, NULL, "xmlns", CX_ATTR);
|
||||
|
||||
/* namespace not found, try parent */
|
||||
|
|
@ -270,6 +271,40 @@ xml2ns(cxobj *x,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Add a namespace attribute to an XML node, either default or specific prefix
|
||||
* @param[in] x XML tree
|
||||
* @param[in] prefix prefix/ns localname. If NULL then set default xmlns
|
||||
* @param[out] namespace URI namespace (or NULL). Will be copied
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see xml2ns
|
||||
*/
|
||||
int
|
||||
xmlns_set(cxobj *x,
|
||||
char *prefix,
|
||||
char *namespace)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xa;
|
||||
|
||||
if (prefix != NULL){ /* xmlns:<prefix>="<uri>" */
|
||||
if ((xa = xml_new(prefix, x, NULL)) == NULL)
|
||||
goto done;
|
||||
if (xml_prefix_set(xa, "xmlns") < 0)
|
||||
goto done;
|
||||
}
|
||||
else{ /* xmlns="<uri>" */
|
||||
if ((xa = xml_new("xmlns", x, NULL)) == NULL)
|
||||
goto done;
|
||||
xml_type_set(xa, CX_ATTR);
|
||||
}
|
||||
if (xml_value_set(xa, namespace) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! See if xmlns:[<localname>=]<uri> exists, if so return <uri>
|
||||
*
|
||||
* @param[in] xn XML node
|
||||
|
|
@ -483,6 +518,8 @@ xml_type_set(cxobj *xn,
|
|||
/*! Get number of children
|
||||
* @param[in] xn xml node
|
||||
* @retval number of children in XML tree
|
||||
* @see xml_child_nr_type
|
||||
* @see xml_child_nr_notype
|
||||
*/
|
||||
int
|
||||
xml_child_nr(cxobj *xn)
|
||||
|
|
@ -490,10 +527,33 @@ xml_child_nr(cxobj *xn)
|
|||
return xn->x_childvec_len;
|
||||
}
|
||||
|
||||
/*! Get number of children of EXCEPT specific type
|
||||
* @param[in] xn xml node
|
||||
* @param[in] type XML type or -1 for all
|
||||
* @retval number of typed children in XML tree (except type)
|
||||
* @see xml_child_nr
|
||||
* @see xml_child_nr_type
|
||||
*/
|
||||
int
|
||||
xml_child_nr_notype(cxobj *xn,
|
||||
enum cxobj_type type)
|
||||
{
|
||||
cxobj *x = NULL;
|
||||
int nr = 0;
|
||||
|
||||
while ((x = xml_child_each(xn, x, -1)) != NULL) {
|
||||
if (xml_type(x) != type)
|
||||
nr++;
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
|
||||
/*! Get number of children of specific type
|
||||
* @param[in] xn xml node
|
||||
* @param[in] type XML type or -1 for all
|
||||
* @retval number of typed children in XML tree
|
||||
* @see xml_child_nr
|
||||
* @see xml_child_nr_notype
|
||||
*/
|
||||
int
|
||||
xml_child_nr_type(cxobj *xn,
|
||||
|
|
@ -521,6 +581,28 @@ xml_child_i(cxobj *xn,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*! Get a specific child of a specific type
|
||||
* @param[in] xn xml node
|
||||
* @param[in] i the number of the child of specific type
|
||||
* @param[in] type Child type
|
||||
* @retval child in XML tree, or NULL if no such child, or empty child
|
||||
* @see xml_child_i
|
||||
*/
|
||||
cxobj *
|
||||
xml_child_i_type(cxobj *xn,
|
||||
int i,
|
||||
enum cxobj_type type)
|
||||
{
|
||||
cxobj *x = NULL;
|
||||
int it = 0;
|
||||
|
||||
while ((x = xml_child_each(xn, x, type)) != NULL) {
|
||||
if (x->x_type == type && (i == it++))
|
||||
return x;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! Set specific child
|
||||
* @param[in] xn xml node
|
||||
* @param[in] i the number of the child, eg order in children vector
|
||||
|
|
@ -938,7 +1020,7 @@ xml_body_get(cxobj *xt)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*! Find and return the value of an xml child of specific type
|
||||
/*! Find and return the value of an xml child of specific type given prefix and name
|
||||
*
|
||||
* The value can be of an attribute only
|
||||
* @param[in] xt xml tree node
|
||||
|
|
@ -950,6 +1032,7 @@ xml_body_get(cxobj *xt)
|
|||
* char *str = xml_find_type_value(x, "prefix", "name", CX_ATTR);
|
||||
* @endcode
|
||||
* @note, make a copy of the return value to use it properly
|
||||
* @see xml_find_type return the xml object
|
||||
* @see xml_find_value where a body can be found as well
|
||||
*/
|
||||
char *
|
||||
|
|
@ -957,6 +1040,32 @@ xml_find_type_value(cxobj *xt,
|
|||
char *prefix,
|
||||
char *name,
|
||||
enum cxobj_type type)
|
||||
{
|
||||
cxobj *x;
|
||||
|
||||
if ((x = xml_find_type(xt, prefix, name, type)) != NULL)
|
||||
return xml_value(x);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! Find and return the xml child of specific type given prefix and name
|
||||
*
|
||||
* The value can be of an attribute only
|
||||
* @param[in] xt xml tree node
|
||||
* @param[in] prefix Prefix (namespace local name) or NULL
|
||||
* @param[in] name name of xml tree node (eg attr name or "body")
|
||||
* @retval val Pointer to the name string
|
||||
* @retval NULL No such node or no value in node
|
||||
* @code
|
||||
* cxobj *x = xml_find_type(x, "prefix", "name", CX_ATTR);
|
||||
* @endcode
|
||||
* @see xml_find_value where a body can be found as well
|
||||
*/
|
||||
cxobj *
|
||||
xml_find_type(cxobj *xt,
|
||||
char *prefix,
|
||||
char *name,
|
||||
enum cxobj_type type)
|
||||
{
|
||||
cxobj *x = NULL;
|
||||
int pmatch; /* prefix match */
|
||||
|
|
@ -969,7 +1078,7 @@ xml_find_type_value(cxobj *xt,
|
|||
else
|
||||
pmatch = 1;
|
||||
if (pmatch && strcmp(name, xml_name(x)) == 0)
|
||||
return xml_value(x);
|
||||
return x;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1397,6 +1506,8 @@ _xml_parse(const char *str,
|
|||
goto done;
|
||||
/* Sort the complete tree after parsing */
|
||||
if (yspec){
|
||||
if (xml_apply0(xt, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
||||
goto done;
|
||||
if (xml_apply0(xt, CX_ELMNT, xml_sort, NULL) < 0)
|
||||
goto done;
|
||||
if (xml_apply0(xt, -1, xml_sort_verify, NULL) < 0)
|
||||
|
|
@ -1592,7 +1703,7 @@ xml_parse_va(cxobj **xtop,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Copy single xml node without copying children
|
||||
/*! Copy single xml node frm x0 to x1 without copying children
|
||||
*/
|
||||
int
|
||||
xml_copy_one(cxobj *x0,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue