diff options
author | Kasimier T. Buchcik <kbuchcik@src.gnome.org> | 2006-02-01 16:36:13 +0000 |
---|---|---|
committer | Kasimier T. Buchcik <kbuchcik@src.gnome.org> | 2006-02-01 16:36:13 +0000 |
commit | e01b2fd77624b30e3ca5c750c379b931b94964f2 (patch) | |
tree | e3b77da17813ee9d6a7e9632add144347e76865b /tree.c | |
parent | 2363555e7649a924cc60a726852d358d6ef404f2 (diff) | |
download | android_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.c | 99 |
1 files changed, 84 insertions, 15 deletions
@@ -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 |