[Lxml-checkins] r46504 - in lxml/branch/lxml-1.3: . src/lxml src/lxml/tests
scoder at codespeak.net
scoder at codespeak.net
Wed Sep 12 15:25:31 CEST 2007
Author: scoder
Date: Wed Sep 12 15:25:31 2007
New Revision: 46504
Modified:
lxml/branch/lxml-1.3/CHANGES.txt
lxml/branch/lxml-1.3/src/lxml/proxy.pxi
lxml/branch/lxml-1.3/src/lxml/serializer.pxi
lxml/branch/lxml-1.3/src/lxml/tests/test_elementtree.py
Log:
merged in namespace serialisation fix from trunk
Modified: lxml/branch/lxml-1.3/CHANGES.txt
==============================================================================
--- lxml/branch/lxml-1.3/CHANGES.txt (original)
+++ lxml/branch/lxml-1.3/CHANGES.txt Wed Sep 12 15:25:31 2007
@@ -2,6 +2,19 @@
lxml changelog
==============
+Under development
+=================
+
+Features added
+--------------
+
+Bugs fixed
+----------
+
+* lxml failed to serialise namespace declarations of elements other than the
+ root node of a tree
+
+
1.3.4 (2007-08-30)
==================
Modified: lxml/branch/lxml-1.3/src/lxml/proxy.pxi
==============================================================================
--- lxml/branch/lxml-1.3/src/lxml/proxy.pxi (original)
+++ lxml/branch/lxml-1.3/src/lxml/proxy.pxi Wed Sep 12 15:25:31 2007
@@ -97,26 +97,6 @@
c_root.children = c_root.last = NULL
tree.xmlFreeDoc(c_doc)
-cdef void _copyParentNamespaces(xmlNode* c_from_node, xmlNode* c_to_node):
- """Copy the namespaces of all ancestors of c_from_node to c_to_node.
-
- This is used in _fakeRootDoc() to avoid loosing namespace declarations.
- """
- cdef xmlNode* c_parent
- cdef xmlNs* c_ns
- cdef xmlNs* c_new_ns
- cdef int prefix_known
- c_parent = c_from_node.parent
- while c_parent is not NULL and tree._isElementOrXInclude(c_parent):
- c_new_ns = c_parent.nsDef
- while c_new_ns is not NULL:
- # check if prefix is already defined
- c_ns = tree.xmlSearchNs(c_to_node.doc, c_to_node, c_new_ns.prefix)
- if c_ns is NULL:
- tree.xmlNewNs(c_to_node, c_new_ns.href, c_new_ns.prefix)
- c_new_ns = c_new_ns.next
- c_parent = c_parent.parent
-
################################################################################
# support for freeing tree elements when proxy objects are destroyed
@@ -177,6 +157,25 @@
################################################################################
# fix _Document references and namespaces when a node changes documents
+cdef void _copyParentNamespaces(xmlNode* c_from_node, xmlNode* c_to_node):
+ """Copy the namespaces of all ancestors of c_from_node to c_to_node.
+ """
+ cdef xmlNode* c_parent
+ cdef xmlNs* c_ns
+ cdef xmlNs* c_new_ns
+ cdef int prefix_known
+ c_parent = c_from_node.parent
+ while c_parent is not NULL and (tree._isElementOrXInclude(c_parent) or
+ c_parent.type == tree.XML_DOCUMENT_NODE):
+ c_new_ns = c_parent.nsDef
+ while c_new_ns is not NULL:
+ # check if prefix is already defined
+ c_ns = tree.xmlSearchNs(c_to_node.doc, c_to_node, c_new_ns.prefix)
+ if c_ns is NULL:
+ tree.xmlNewNs(c_to_node, c_new_ns.href, c_new_ns.prefix)
+ c_new_ns = c_new_ns.next
+ c_parent = c_parent.parent
+
cdef void moveNodeToDocument(_Document doc, xmlNode* c_element):
"""Fix the xmlNs pointers of a node and its subtree that were moved.
Modified: lxml/branch/lxml-1.3/src/lxml/serializer.pxi
==============================================================================
--- lxml/branch/lxml-1.3/src/lxml/serializer.pxi (original)
+++ lxml/branch/lxml-1.3/src/lxml/serializer.pxi Wed Sep 12 15:25:31 2007
@@ -79,14 +79,37 @@
int write_complete_document,
int pretty_print):
cdef xmlDoc* c_doc
+ cdef xmlNode* c_nsdecl_node
c_doc = c_node.doc
if write_xml_declaration:
_writeDeclarationToBuffer(c_buffer, c_doc.version, encoding)
+ # write internal DTD subset, preceding PIs/comments, etc.
if write_complete_document:
_writeDtdToBuffer(c_buffer, c_doc, c_node.name, encoding)
_writePrevSiblings(c_buffer, c_node, encoding, pretty_print)
- tree.xmlNodeDumpOutput(c_buffer, c_doc, c_node, 0, pretty_print, encoding)
+
+ c_nsdecl_node = c_node
+ if c_node.parent is NULL or c_node.parent.type != tree.XML_DOCUMENT_NODE:
+ # copy the node and add namespaces from parents
+ # this is required to make libxml write them
+ c_nsdecl_node = tree.xmlCopyNode(c_node, 2)
+ _copyParentNamespaces(c_node, c_nsdecl_node)
+
+ c_nsdecl_node.parent = c_node.parent
+ c_nsdecl_node.children = c_node.children
+ c_nsdecl_node.last = c_node.last
+
+ # write node
+ tree.xmlNodeDumpOutput(c_buffer, c_doc, c_nsdecl_node, 0,
+ pretty_print, encoding)
+
+ if c_nsdecl_node is not c_node:
+ # clean up
+ c_nsdecl_node.children = c_nsdecl_node.last = NULL
+ tree.xmlFreeNode(c_nsdecl_node)
+
+ # write tail, trailing comments, etc.
_writeTail(c_buffer, c_node, encoding, pretty_print)
if write_complete_document:
_writeNextSiblings(c_buffer, c_node, encoding, pretty_print)
Modified: lxml/branch/lxml-1.3/src/lxml/tests/test_elementtree.py
==============================================================================
--- lxml/branch/lxml-1.3/src/lxml/tests/test_elementtree.py (original)
+++ lxml/branch/lxml-1.3/src/lxml/tests/test_elementtree.py Wed Sep 12 15:25:31 2007
@@ -1969,6 +1969,37 @@
del one
self.assertEquals('{http://a.b.c}baz', baz.tag)
+ def test_ns_decl(self):
+ tostring = self.etree.tostring
+ root = self.etree.XML(
+ '<foo><bar xmlns:ns="http://a.b.c"><ns:baz/></bar></foo>')
+ baz = root[0][0]
+
+ nsdecl = re.findall("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']",
+ tostring(baz))
+ self.assertEquals(["http://a.b.c"], nsdecl)
+
+ def test_ns_decl_default(self):
+ tostring = self.etree.tostring
+ root = self.etree.XML(
+ '<foo><bar xmlns="http://a.b.c"><baz/></bar></foo>')
+ baz = root[0][0]
+
+ nsdecl = re.findall("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']",
+ tostring(baz))
+ self.assertEquals(["http://a.b.c"], nsdecl)
+
+ def test_ns_decl_root(self):
+ tostring = self.etree.tostring
+ root = self.etree.XML(
+ '<foo xmlns:ns="http://a.b.c"><bar><ns:baz/></bar></foo>')
+ baz = root[0][0]
+
+ nsdecl = re.findall("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']",
+ tostring(baz))
+
+ self.assertEquals(["http://a.b.c"], nsdecl)
+
def test_attribute_xmlns_move(self):
Element = self.etree.Element
More information about the lxml-checkins
mailing list