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
diff --git a/tree.c b/tree.c
index ba3cbf2..b3eea54 100644
--- a/tree.c
+++ b/tree.c
@@ -5274,6 +5274,16 @@
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;
}
@@ -5281,6 +5291,50 @@
}
/**
+ * 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
* @node: the current node
@@ -5291,84 +5345,82 @@
* 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);
}
/**