aboutsummaryrefslogtreecommitdiffstats
path: root/tree.c
diff options
context:
space:
mode:
authorKasimier T. Buchcik <kbuchcik@src.gnome.org>2006-02-01 16:36:13 +0000
committerKasimier T. Buchcik <kbuchcik@src.gnome.org>2006-02-01 16:36:13 +0000
commite01b2fd77624b30e3ca5c750c379b931b94964f2 (patch)
treee3b77da17813ee9d6a7e9632add144347e76865b /tree.c
parent2363555e7649a924cc60a726852d358d6ef404f2 (diff)
downloadandroid_external_libxml2-e01b2fd77624b30e3ca5c750c379b931b94964f2.tar.gz
android_external_libxml2-e01b2fd77624b30e3ca5c750c379b931b94964f2.tar.bz2
android_external_libxml2-e01b2fd77624b30e3ca5c750c379b931b94964f2.zip
Enhanced xmlDOMWrapReconcileNamespaces() to remove redundant ns-decls if
* tree.c: Enhanced xmlDOMWrapReconcileNamespaces() to remove redundant ns-decls if the option XML_DOM_RECONNS_REMOVEREDUND was given. Note that I haven't moved this option to the header file yet; so just call this function with an @option of 1 to test the behaviour.
Diffstat (limited to 'tree.c')
-rw-r--r--tree.c99
1 files changed, 84 insertions, 15 deletions
diff --git a/tree.c b/tree.c
index f6076885..9b71b7fa 100644
--- a/tree.c
+++ b/tree.c
@@ -7291,9 +7291,9 @@ struct xmlNsMapItem {
* depth:
* >= 0 == @node's ns-decls
* -1 == @parent's ns-decls
- * -2 == @parent's out-of-scope ns-decls
- * -3 == the doc->oldNs XML ns-decl
- * -4 == the doc->oldNs storage ns-decls
+ * -2 == the doc->oldNs XML ns-decl
+ * -3 == the doc->oldNs storage ns-decls
+ * -4 == ns-decls provided via custom ns-handling
*/
int depth;
};
@@ -7488,7 +7488,7 @@ xmlTreeNSListLookupByPrefix(xmlNsPtr nsList, const xmlChar *prefix)
/*
*
-* xmlTreeGetInScopeNamespaces:
+* xmlDOMWrapNSNormGatherInScopeNs:
* @map: the namespace map
* @node: the node to start with
*
@@ -8069,6 +8069,10 @@ xmlDOMWrapNSNormAquireNormalizedNs(xmlDocPtr doc,
return (0);
}
+typedef enum {
+ XML_DOM_RECONNS_REMOVEREDUND = 1<<0
+} xmlDOMReconcileNSOptions;
+
/*
* xmlDOMWrapReconcileNamespaces:
* @ctxt: DOM wrapper context, unused at the moment
@@ -8083,19 +8087,24 @@ xmlDOMWrapNSNormAquireNormalizedNs(xmlDocPtr doc,
* WARNING: This function is in a experimental state.
*
* Returns 0 if succeeded, -1 otherwise and on API/internal errors.
-*/
+*/
+
int
xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
xmlNodePtr elem,
- int options ATTRIBUTE_UNUSED)
+ int options)
{
int depth = -1, adoptns = 0, parnsdone = 0;
- xmlNsPtr ns;
+ xmlNsPtr ns, prevns;
xmlDocPtr doc;
xmlNodePtr cur, curElem = NULL;
xmlNsMapItemPtr nsMap = NULL, topmi = NULL, mi;
/* @ancestorsOnly should be set by an option flag. */
int ancestorsOnly = 0;
+ int optRemoveDedundantNS =
+ ((xmlDOMReconcileNSOptions) options & XML_DOM_RECONNS_REMOVEREDUND) ? 1 : 0;
+ xmlNsPtr *listRedund = NULL;
+ int sizeRedund = 0, nbRedund = 0, ret, i, j;
if ((elem == NULL) || (elem->doc == NULL) ||
(elem->type != XML_ELEMENT_NODE))
@@ -8113,6 +8122,7 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
* Namespace declarations.
*/
if (cur->nsDef != NULL) {
+ prevns = NULL;
for (ns = cur->nsDef; ns != NULL; ns = ns->next) {
if (! parnsdone) {
if ((elem->parent) &&
@@ -8128,6 +8138,38 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
}
parnsdone = 1;
}
+
+ /*
+ * Lookup the ns ancestor-axis for equal ns-decls in scope.
+ */
+ if (optRemoveDedundantNS && nsMap) {
+ for (mi = nsMap; mi != topmi->next; mi = mi->next) {
+ if ((mi->depth >= XML_TREE_NSMAP_PARENT) &&
+ (mi->shadowDepth == -1) &&
+ ((ns->prefix == mi->newNs->prefix) ||
+ xmlStrEqual(ns->prefix, mi->newNs->prefix)) &&
+ ((ns->href == mi->newNs->href) ||
+ xmlStrEqual(ns->href, mi->newNs->href)))
+ {
+ /*
+ * A redundant ns-decl was found.
+ * Add it to the list of redundant ns-decls.
+ */
+ if (xmlDOMWrapNSNormAddNsMapItem2(&listRedund,
+ &sizeRedund, &nbRedund, ns, mi->newNs) == -1)
+ goto internal_error;
+ /*
+ * Remove the ns-decl from the element-node.
+ */
+ if (prevns)
+ prevns->next = ns->next;
+ else
+ cur->nsDef = ns->next;
+ goto adopt_ns;
+ }
+ }
+ }
+
/*
* Skip ns-references handling if the referenced
* ns-decl is declared on the same element.
@@ -8154,15 +8196,19 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
if (xmlDOMWrapNSNormAddNsMapItem(&nsMap, &topmi, ns, ns,
depth) == NULL)
goto internal_error;
+
+ prevns = ns;
}
}
if (! adoptns)
goto ns_end;
-
+adopt_ns:
/* No break on purpose. */
case XML_ATTRIBUTE_NODE:
+ /* No ns, no fun. */
if (cur->ns == NULL)
goto ns_end;
+
if (! parnsdone) {
if ((elem->parent) &&
((xmlNodePtr) elem->parent->doc != elem->parent)) {
@@ -8175,6 +8221,17 @@ xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt ATTRIBUTE_UNUSED,
parnsdone = 1;
}
/*
+ * Adjust the reference if this was a redundant ns-decl.
+ */
+ if (listRedund) {
+ for (i = 0, j = 0; i < nbRedund; i++, j += 2) {
+ if (cur->ns == listRedund[j]) {
+ cur->ns = listRedund[++j];
+ break;
+ }
+ }
+ }
+ /*
* Adopt ns-references.
*/
if (nsMap != NULL) {
@@ -8214,6 +8271,7 @@ ns_end:
default:
goto next_sibling;
}
+into_content:
if ((cur->type == XML_ELEMENT_NODE) &&
(cur->children != NULL)) {
/*
@@ -8244,18 +8302,29 @@ next_sibling:
if (cur->next != NULL)
cur = cur->next;
else {
+ if (cur->type == XML_ATTRIBUTE_NODE) {
+ cur = cur->parent;
+ goto into_content;
+ }
cur = cur->parent;
goto next_sibling;
}
} while (cur != NULL);
-
- if (nsMap != NULL)
- xmlDOMWrapNSNormFreeNsMap(nsMap);
- return (0);
+
+ ret = 0;
+ goto exit;
internal_error:
+ ret = -1;
+exit:
+ if (listRedund) {
+ for (i = 0, j = 0; i < nbRedund; i++, j += 2) {
+ xmlFreeNs(listRedund[j]);
+ }
+ xmlFree(listRedund);
+ }
if (nsMap != NULL)
- xmlDOMWrapNSNormFreeNsMap(nsMap);
- return (-1);
+ xmlDOMWrapNSNormFreeNsMap(nsMap);
+ return (ret);
}
/*
@@ -8264,7 +8333,7 @@ internal_error:
* @sourceDoc: the optional sourceDoc
* @node: the element-node to start with
* @destDoc: the destination doc for adoption
-* @parent: the optional new parent of @node in @destDoc
+* @destParent: the optional new parent of @node in @destDoc
* @options: option flags
*
* Ensures that ns-references point to @destDoc: either to