applied speedup to xmlSearchNs() as suggested by Luca Padovani. Cleaned up

* tree.c: applied speedup to xmlSearchNs() as suggested by
  Luca Padovani. Cleaned up xmlSearchNsByHref() in the process
  applying the same trick.
Daniel
This commit is contained in:
Daniel Veillard 2003-09-12 09:44:56 +00:00
parent e72f42c168
commit 2a3fea37e1
2 changed files with 128 additions and 70 deletions

View File

@ -1,3 +1,9 @@
Fri Sep 12 11:43:12 CEST 2003 Daniel Veillard <daniel@veillard.com>
* tree.c: applied speedup to xmlSearchNs() as suggested by
Luca Padovani. Cleaned up xmlSearchNsByHref() in the process
applying the same trick.
Fri Sep 12 01:36:20 CEST 2003 Daniel Veillard <daniel@veillard.com>
* parser.c parserInternals.c tree.c include/libxml/parser.h

192
tree.c
View File

@ -5274,12 +5274,66 @@ xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace) {
return(cur);
cur = cur->next;
}
cur = node->ns;
if (cur != NULL) {
if ((cur->prefix == NULL) && (nameSpace == NULL) &&
(cur->href != NULL))
return(cur);
if ((cur->prefix != NULL) && (nameSpace != NULL) &&
(cur->href != NULL) &&
(xmlStrEqual(cur->prefix, nameSpace)))
return(cur);
}
}
node = node->parent;
}
return(NULL);
}
/**
* xmlNsInScope:
* @doc: the document
* @node: the current node
* @ancestor: the ancestor carrying the namespace
* @prefix: the namespace prefix
*
* Verify that the given namespace held on @ancestor is still in scope
* on node.
*
* Returns 1 if true, 0 if false and -1 in case of error.
*/
static int
xmlNsInScope(xmlDocPtr doc, xmlNodePtr node, xmlNodePtr ancestor,
const xmlChar * prefix)
{
xmlNsPtr tst;
while ((node != NULL) && (node != ancestor)) {
if ((node->type == XML_ENTITY_REF_NODE) ||
(node->type == XML_ENTITY_NODE) ||
(node->type == XML_ENTITY_DECL))
return (-1);
if (node->type == XML_ELEMENT_NODE) {
tst = node->nsDef;
while (tst != NULL) {
if ((tst->prefix == NULL)
&& (prefix == NULL))
return (0);
if ((tst->prefix != NULL)
&& (prefix != NULL)
&& (xmlStrEqual(tst->prefix, prefix)))
return (0);
tst = tst->next;
}
}
node = node->parent;
}
if (node != ancestor)
return (-1);
return (1);
}
/**
* xmlSearchNsByHref:
* @doc: the document
@ -5291,84 +5345,82 @@ xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace) {
* Returns the namespace pointer or NULL.
*/
xmlNsPtr
xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar *href) {
xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar * href)
{
xmlNsPtr cur;
xmlNodePtr orig = node;
if ((node == NULL) || (href == NULL)) return(NULL);
if ((node == NULL) || (href == NULL))
return (NULL);
if (xmlStrEqual(href, XML_XML_NAMESPACE)) {
/*
* Only the document can hold the XML spec namespace.
*/
if ((doc == NULL) && (node->type == XML_ELEMENT_NODE)) {
/*
* The XML-1.0 namespace is normally held on the root
* element. In this case exceptionally create it on the
* node element.
*/
cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
if (cur == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlSearchNs : malloc failed\n");
return(NULL);
}
memset(cur, 0, sizeof(xmlNs));
cur->type = XML_LOCAL_NAMESPACE;
cur->href = xmlStrdup(XML_XML_NAMESPACE);
cur->prefix = xmlStrdup((const xmlChar *)"xml");
cur->next = node->nsDef;
node->nsDef = cur;
return(cur);
}
if (doc->oldNs == NULL) {
/*
* Allocate a new Namespace and fill the fields.
*/
doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
if (doc->oldNs == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlSearchNsByHref : malloc failed\n");
return(NULL);
}
memset(doc->oldNs, 0, sizeof(xmlNs));
doc->oldNs->type = XML_LOCAL_NAMESPACE;
/*
* Only the document can hold the XML spec namespace.
*/
if ((doc == NULL) && (node->type == XML_ELEMENT_NODE)) {
/*
* The XML-1.0 namespace is normally held on the root
* element. In this case exceptionally create it on the
* node element.
*/
cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
if (cur == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlSearchNs : malloc failed\n");
return (NULL);
}
memset(cur, 0, sizeof(xmlNs));
cur->type = XML_LOCAL_NAMESPACE;
cur->href = xmlStrdup(XML_XML_NAMESPACE);
cur->prefix = xmlStrdup((const xmlChar *) "xml");
cur->next = node->nsDef;
node->nsDef = cur;
return (cur);
}
if (doc->oldNs == NULL) {
/*
* Allocate a new Namespace and fill the fields.
*/
doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
if (doc->oldNs == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlSearchNsByHref : malloc failed\n");
return (NULL);
}
memset(doc->oldNs, 0, sizeof(xmlNs));
doc->oldNs->type = XML_LOCAL_NAMESPACE;
doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE);
doc->oldNs->prefix = xmlStrdup((const xmlChar *)"xml");
}
return(doc->oldNs);
doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE);
doc->oldNs->prefix = xmlStrdup((const xmlChar *) "xml");
}
return (doc->oldNs);
}
while (node != NULL) {
cur = node->nsDef;
while (cur != NULL) {
if ((cur->href != NULL) && (href != NULL) &&
(xmlStrEqual(cur->href, href))) {
/*
* Check that the prefix is not shadowed between orig and node
*/
xmlNodePtr check = orig;
xmlNsPtr tst;
while (check != node) {
tst = check->nsDef;
while (tst != NULL) {
if ((tst->prefix == NULL) && (cur->prefix == NULL))
goto shadowed;
if ((tst->prefix != NULL) && (cur->prefix != NULL) &&
(xmlStrEqual(tst->prefix, cur->prefix)))
goto shadowed;
tst = tst->next;
}
check = check->parent;
}
return(cur);
}
shadowed:
cur = cur->next;
}
node = node->parent;
if ((node->type == XML_ENTITY_REF_NODE) ||
(node->type == XML_ENTITY_NODE) ||
(node->type == XML_ENTITY_DECL))
return (NULL);
if (node->type == XML_ELEMENT_NODE) {
cur = node->nsDef;
while (cur != NULL) {
if ((cur->href != NULL) && (href != NULL) &&
(xmlStrEqual(cur->href, href))) {
if (xmlNsInScope(doc, orig, node, cur->href) == 1)
return (cur);
}
cur = cur->next;
}
cur = node->ns;
if (cur != NULL) {
if ((cur->href != NULL) && (href != NULL) &&
(xmlStrEqual(cur->href, href))) {
if (xmlNsInScope(doc, orig, node, cur->href) == 1)
return (cur);
}
}
}
node = node->parent;
}
return(NULL);
return (NULL);
}
/**