* Optimized prefix checks at xml parse time: using many prefixes slowed down parsing considerably
* Cleared startup-db cache after restart
This commit is contained in:
parent
5b57e68e2b
commit
b8ec6a4957
12 changed files with 232 additions and 139 deletions
|
|
@ -424,7 +424,6 @@ xml_nsctx_yangspec(yang_stmt *yspec,
|
|||
* if (xml2ns(xt, NULL, &namespace) < 0)
|
||||
* err;
|
||||
* @endcode
|
||||
* @see xmlns_check
|
||||
* @see xmlns_set cache is set
|
||||
* @note, this function uses a cache.
|
||||
*/
|
||||
|
|
@ -474,6 +473,38 @@ xml2ns(cxobj *x,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Recursively check prefix / namespaces (and populate ns cache)
|
||||
* @retval 1 OK
|
||||
* @retval 0 (Some) prefix not found
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
xml2ns_recurse(cxobj *xt)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *x;
|
||||
char *prefix;
|
||||
char *namespace;
|
||||
|
||||
x = NULL;
|
||||
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) {
|
||||
if ((prefix = xml_prefix(x)) != NULL){
|
||||
namespace = NULL;
|
||||
if (xml2ns(x, prefix, &namespace) < 0)
|
||||
goto done;
|
||||
if (namespace == NULL){
|
||||
clicon_err(OE_XML, ENOENT, "No namespace associated with %s:%s", prefix, xml_name(x));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (xml2ns_recurse(x) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
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
|
||||
|
|
@ -573,64 +604,3 @@ xml2prefix(cxobj *xn,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*! See if xmlns:[<localname>=]<uri> exists, if so return <uri>
|
||||
*
|
||||
* @param[in] xn XML node
|
||||
* @param[in] nsn Namespace name
|
||||
* @retval URI return associated URI if found
|
||||
* @retval NULL No namespace name binding found for nsn
|
||||
* @see xml2ns XXX coordinate
|
||||
*/
|
||||
static char *
|
||||
xmlns_check(cxobj *xn,
|
||||
char *nsn)
|
||||
{
|
||||
cxobj *x = NULL;
|
||||
char *xns;
|
||||
|
||||
while ((x = xml_child_each(xn, x, CX_ATTR)) != NULL)
|
||||
if ((xns = xml_prefix(x)) && strcmp(xns, "xmlns")==0 &&
|
||||
strcmp(xml_name(x), nsn) == 0)
|
||||
return xml_value(x);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! Check namespace of xml node by searching recursively among ancestors
|
||||
* @param[in] xn xml node
|
||||
* @param[in] namespace check validity of namespace
|
||||
* @retval 0 Found / validated or no yang spec
|
||||
* @retval -1 Not found
|
||||
* @note This function is grossly inefficient
|
||||
*/
|
||||
int
|
||||
xml_localname_check(cxobj *xn,
|
||||
void *arg)
|
||||
{
|
||||
cxobj *xp = NULL;
|
||||
char *nsn;
|
||||
char *n;
|
||||
yang_stmt *ys = xml_spec(xn);
|
||||
|
||||
/* No namespace name - comply */
|
||||
if ((nsn = xml_prefix(xn)) == NULL)
|
||||
return 0;
|
||||
/* Check if NSN defined in same node */
|
||||
if (xmlns_check(xn, nsn) != NULL)
|
||||
return 0;
|
||||
/* Check if NSN defined in some ancestor */
|
||||
while ((xp = xml_parent(xn)) != NULL) {
|
||||
if (xmlns_check(xp, nsn) != NULL)
|
||||
return 0;
|
||||
xn = xp;
|
||||
}
|
||||
/* Check if my namespace */
|
||||
if ((n = yang_find_myprefix(ys)) != NULL && strcmp(nsn,n)==0)
|
||||
return 0;
|
||||
/* Check if any imported module */
|
||||
if (yang_find_module_by_prefix(ys, nsn) != NULL)
|
||||
return 0;
|
||||
/* Not found, error */
|
||||
clicon_err(OE_XML, ENOENT, "Namespace name %s in %s:%s not found",
|
||||
nsn, nsn, xml_name(xn));
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue