Author: faassen
Date: Thu May 19 20:27:42 2005
New Revision: 12568
Modified:
lxml/trunk/CHANGES.txt
lxml/trunk/src/lxml/etree.pyx
lxml/trunk/src/lxml/tests/test_etree.py
lxml/trunk/src/lxml/tree.pxd
Log:
Fix namespace related issues with moving nodes by fixing up namespaces
using xmlReconciliateNs().
Modified: lxml/trunk/CHANGES.txt
==============================================================================
--- lxml/trunk/CHANGES.txt (original)
+++ lxml/trunk/CHANGES.txt Thu May 19 20:27:42 2005
@@ -24,6 +24,10 @@
problems when deallocating these documents later if they contained a
node that came from a document with a dictionary.
+* Moving namespaced elements between documents was problematic as
+ references to the original document would remain. This has been fixed
+ by applying xmlReconciliateNs() after each move operation.
+
0.6 (2005-05-14)
================
Modified: lxml/trunk/src/lxml/etree.pyx
==============================================================================
--- lxml/trunk/src/lxml/etree.pyx (original)
+++ lxml/trunk/src/lxml/etree.pyx Thu May 19 20:27:42 2005
@@ -1681,8 +1681,14 @@
A node can change document in certain operations as an XML
subtree can move. This updates all possible proxies in the
- tree below (including the current node).
+ tree below (including the current node). It also reconciliates
+ namespaces so they're correct inside the new environment.
"""
+ changeDocumentBelowHelper(c_node, doc)
+ tree.xmlReconciliateNs(doc._c_doc, c_node)
+
+cdef void changeDocumentBelowHelper(xmlNode* c_node,
+ _DocumentBase doc):
cdef ProxyRef* ref
cdef xmlNode* c_current
cdef xmlAttr* c_attr_current
@@ -1703,13 +1709,13 @@
# adjust all children
c_current = c_node.children
while c_current is not NULL:
- changeDocumentBelow(c_current, doc)
+ changeDocumentBelowHelper(c_current, doc)
c_current = c_current.next
# adjust all attributes
c_attr_current = c_node.properties
while c_attr_current is not NULL:
- changeDocumentBelow(c_current, doc)
+ changeDocumentBelowHelper(c_current, doc)
c_attr_current = c_attr_current.next
cdef void attemptDeallocation(xmlNode* c_node):
Modified: lxml/trunk/src/lxml/tests/test_etree.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_etree.py (original)
+++ lxml/trunk/src/lxml/tests/test_etree.py Thu May 19 20:27:42 2005
@@ -1247,8 +1247,9 @@
self.assertEquals('{%s}b' % ns2,
b.tag)
self.assertEquals(
- '<ns0:a xmlns:ns0="%s"><ns1:b xmlns:ns1="%s"></ns1:b></ns0:a>' %
(ns, ns2),
- self._writeElement(a))
+ '{%s}a' % ns, a.tag)
+ self.assertEquals(
+ '{%s}b' % ns2, b.tag)
def test_ns_attr(self):
Element = self.etree.Element
@@ -1267,6 +1268,21 @@
'<a xmlns:ns0="%s" xmlns:ns1="%s" ns0:foo="Foo"
ns1:bar="Bar"></a>' % (ns, ns2),
self._writeElement(a))
+ def test_ns_move(self):
+ Element = self.etree.Element
+ ElementTree = self.etree.ElementTree
+
+ one = self.etree.parse(
+ StringIO('<foo><bar
xmlns:ns="http://a.b.c"><ns:baz/></bar></foo>'))
+ baz = one.getroot()[0][0]
+
+ two = ElementTree(Element('root'))
+ two.getroot().append(baz)
+ # removing the originating document could cause a crash/error before
+ # as namespace is not moved along with it
+ del one
+ self.assertEquals('{http://a.b.c}baz', baz.tag)
+
def test_tostring(self):
tostring = self.etree.tostring
Element = self.etree.Element
Modified: lxml/trunk/src/lxml/tree.pxd
==============================================================================
--- lxml/trunk/src/lxml/tree.pxd (original)
+++ lxml/trunk/src/lxml/tree.pxd Thu May 19 20:27:42 2005
@@ -145,7 +145,8 @@
int format, char* encoding)
cdef void xmlNodeSetName(xmlNode* cur, char* name)
cdef xmlDoc* xmlCopyDoc(xmlDoc* doc, int recursive)
-
+ cdef int xmlReconciliateNs(xmlDoc* doc, xmlNode* tree)
+
cdef extern from "libxml/xmlIO.h":
cdef xmlOutputBuffer* xmlOutputBufferCreateFile(
FILE* file,
|