Hi,
libxml2 currently does not handle namespaces correctly in all cases when cloning
nodes.
I have attached a testcase(which demonstrates the bug using libgdome2.0.8.1 on
top of libxml2.2.6.23), and a patch for the issue.
The testcase tests 4 different cases, which you access by compiling with
-DTESTNUMBER=0 through to -DTESTNUMBER=3
Please CC any responses to me, as I am not on the xml@ list.
Best regards,
Andrew Miller
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
--- tree.c.orig 2006-02-20 14:51:28.428448035 +1300
+++ tree.c 2006-02-20 16:05:42.781217208 +1300
@@ -3872,7 +3872,10 @@
if (node->ns != NULL) {
xmlNsPtr ns;
- ns = xmlSearchNs(doc, ret, node->ns->prefix);
+ if (node->ns->prefix == NULL || node->doc != doc)
+ ns = NULL;
+ else
+ ns = xmlSearchNs(doc, ret, node->ns->prefix);
if (ns == NULL) {
/*
* Humm, we are copying an element whose namespace is defined
@@ -3883,9 +3886,13 @@
if (ns != NULL) {
xmlNodePtr root = ret;
- while (root->parent != NULL) root = root->parent;
+ while (root->parent != NULL &&
+ root->parent->type == XML_ELEMENT_NODE)
+ root = root->parent;
ret->ns = xmlNewNs(root, ns->href, ns->prefix);
}
+ else
+ ret->ns = xmlNewNs(NULL, node->ns->href, node->ns->prefix);
} else {
/*
* reference the existing namespace definition in our own tree.
#include <libgdome/gdome.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#if TESTNUMBER & 1
#define CLONE_WHOLE_DOCUMENT
#endif
#if TESTNUMBER & 2
#define INCLUDE_PREFIX
#endif
int
main(int argc, char** argv)
{
GdomeException exc;
GdomeDOMImplementation *impl;
GdomeDocumentType *dt;
GdomeDocument *doc1
#ifdef CLONE_WHOLE_DOCUMENT
, *doc2
#endif
;
GdomeElement *de1, *de2;
GdomeDOMString *str1, *str2, *str3;
impl = gdome_di_mkref();
assert(impl);
str1 = gdome_str_mkref_own(strdup("foo"));
str2 = gdome_str_mkref_own(strdup("bar"));
str3 = gdome_str_mkref_own(strdup("baz"));
dt = gdome_di_createDocumentType(impl, str1, str2,
str3, &exc);
gdome_str_unref(str1);
gdome_str_unref(str2);
gdome_str_unref(str3);
assert(GDOME_EXCEPTION_CODE(exc) == GDOME_NOEXCEPTION_ERR);
assert(dt);
str1 = gdome_str_mkref_own(strdup("http://www.example.org/URN/testcase"));
str2 = gdome_str_mkref_own(strdup(
#ifdef INCLUDE_PREFIX
"myel:"
#endif
"testelement"));
doc1 = gdome_di_createDocument(impl, str1, str2, dt, &exc);
gdome_str_unref(str1);
gdome_str_unref(str2);
assert(GDOME_EXCEPTION_CODE(exc) == GDOME_NOEXCEPTION_ERR);
assert(doc1);
#ifdef CLONE_WHOLE_DOCUMENT
doc2 = GDOME_DOC(gdome_doc_cloneNode(doc1, TRUE, &exc));
assert(GDOME_EXCEPTION_CODE(exc) == GDOME_NOEXCEPTION_ERR);
assert(doc2);
#endif
de1 = gdome_doc_documentElement(doc1, &exc);
assert(GDOME_EXCEPTION_CODE(exc) == GDOME_NOEXCEPTION_ERR);
assert(de1);
#ifdef CLONE_WHOLE_DOCUMENT
de2 = gdome_doc_documentElement(doc2, &exc);
assert(GDOME_EXCEPTION_CODE(exc) == GDOME_NOEXCEPTION_ERR);
#else
de2 = GDOME_EL(gdome_el_cloneNode(de1, TRUE, &exc));
assert(GDOME_EXCEPTION_CODE(exc) == GDOME_NOEXCEPTION_ERR);
#endif
assert(de2);
str1 = gdome_el_namespaceURI(de1, &exc);
assert(GDOME_EXCEPTION_CODE(exc) == GDOME_NOEXCEPTION_ERR);
assert(str1);
assert(str1->str);
str2 = gdome_el_namespaceURI(de2, &exc);
assert(GDOME_EXCEPTION_CODE(exc) == GDOME_NOEXCEPTION_ERR);
assert(str2);
assert(str2->str);
printf("de1->namespaceURI() = %s\n"
"de2->namespaceURI() = %s\n",
str1->str, str2->str);
return 0;
}
_______________________________________________
xml mailing list, project page http://xmlsoft.org/
[email protected]
http://mail.gnome.org/mailman/listinfo/xml