[xml] xmlReconciliateNs problem
- From: Petr Pajas <pajas ufal ms mff cuni cz>
- To: xml gnome org
- Subject: [xml] xmlReconciliateNs problem
- Date: Mon, 27 Oct 2003 20:26:55 +0100
Hi Daniel, All,
I'm trying to make XML::LibXML perl module work with 2.6. After
examining one of the self tests that broke after upgrade, I suspect that
xmlReconciliateNs doesn't do its right job (if at all). The
documentation says:
"This function checks that all the namespaces declared within the given
tree are properly declared. This is needed for example after Copy or Cut
and then paste operations. ..."
Now, I have a document like this:
<?xml version="1.0"?>
<foo><x:a xmlns:x="http://foo.bar"><x:b/></x:a></foo>
and try either:
a) move <x:b/> one level up, into <foo>
b) move <x:b/> into another document
in both cases, expecting xmlReconciliateNs to create
xmlns:x="http://foo.bar" on <x:b/>. This is at least what it used to do
with libxml2-2.5.x.
The attached file is my lame attempt of rewriting of the test case into
C. It demonstrates the problem in the following way:
1) run it without parameters to check for a)
2) run it with 1 parameter (arbitrary) to check for b)
3) run it with 2 parameter (-"-) to check for b), freeing the original
document as soon as <x:b> was moved and namespaces reconciliated.
I compile it with:
gcc -I /usr/include/libxml2 -L /usr/lib -lxml2 -o testns testns.c
with 2.6, I get
1) ./testns
<?xml version="1.0"?>
<foo><x:a xmlns:x="http://foo.bar"/><x:b/></foo>
(bad: x:b has prefix but no namespace declared)
2) ./testns x
<?xml version="1.0"?>
<x:b/>
(bad)
3) ./testns x x
<?xml version="1.0"?>
<b/>
(even worse - maybe because of the new string reusing code?)
while with 2.5.3:
1) ./testns
<?xml version="1.0"?>
<foo><x:a xmlns:x="http://foo.bar"/><x:b xmlns:x="http://foo.bar"/></foo>
2) ./testns x
<?xml version="1.0"?>
<x:b xmlns:x="http://foo.bar"/>
3) ./testns x x
<?xml version="1.0"?>
<x:b xmlns:x="http://foo.bar"/>
which all look well.
I looked into the corresponding tree.c code. It appears, that
xmlReconciliateNs simply does nothing, being fooled by xmlSearchNsByHref
which returns node->ns even though it failed to find a corresponding nsDef.
If the behavior of 2.6 is intended, is there a workaround?
Thanks,
-- Petr
#include <libxml/tree.h>
#include <libxml/parser.h>
#define COPY_BETWEEN_DOCUMENTS 1
/*
* The document
*/
static xmlChar buffer[] =
"<?xml version=\"1.0\"?>\n\
<foo><x:a xmlns:x=\"http://foo.bar\"><x:b/></x:a></foo>\n";
int main(int argc, char **argv) {
xmlDocPtr doc1 = NULL;
xmlDocPtr doc2 = NULL;
xmlNodePtr node = NULL;
xmlNodePtr foo = NULL;
xmlChar *buf = NULL;
int len = 0;
int copy_between_documents=0;
int free_doc1_soon=0;
if (argc>1) copy_between_documents = 1;
if (argc>2) free_doc1_soon = 1;
doc1 = xmlParseDoc(buffer);
foo=xmlDocGetRootElement(doc1); /* foo */
node=foo->children->children; /* x:b */
if (copy_between_documents) {
/* move x:b to a new document */
doc2 = xmlNewDoc((const xmlChar*) "1.0");
xmlSetTreeDoc(node, doc2); /* doc2 adopts node */
node->doc=doc2;
xmlDocSetRootElement( doc2, node );
xmlReconciliateNs(doc2, node); /* fix namespaces */
if (free_doc1_soon) { /* free doc1 now?*/
if (doc1) xmlFreeDoc(doc1);
doc1=NULL;
}
xmlDocDumpMemory(doc2, &buf, &len);
} else {
/* raise x:b 1 level into foo */
xmlUnlinkNode( node );
xmlAddChild( foo, node );
xmlReconciliateNs(doc1, node); /* fix namespaces */
xmlDocDumpMemory(doc1, &buf, &len);
}
printf("%s",buf);
if (buf) xmlFree(buf);
if (doc1) xmlFreeDoc(doc1);
if (doc2) xmlFreeDoc(doc2);
xmlCleanupParser();
xmlMemoryDump();
return(0);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]