[Lxml-checkins] r46501 - in lxml/trunk: . src/lxml
scoder at codespeak.net
scoder at codespeak.net
Wed Sep 12 14:56:03 CEST 2007
Author: scoder
Date: Wed Sep 12 14:56:01 2007
New Revision: 46501
Modified:
lxml/trunk/CHANGES.txt
lxml/trunk/src/lxml/proxy.pxi
lxml/trunk/src/lxml/serializer.pxi
Log:
work around libxml2's failure to serialise namespace declarations
Modified: lxml/trunk/CHANGES.txt
==============================================================================
--- lxml/trunk/CHANGES.txt (original)
+++ lxml/trunk/CHANGES.txt Wed Sep 12 14:56:01 2007
@@ -17,6 +17,9 @@
Bugs fixed
----------
+* lxml failed to serialise namespace declarations of elements other than the
+ root node of a tree
+
* Race condition in XSLT where the resolver context leaked between concurrent
XSLT calls
Modified: lxml/trunk/src/lxml/proxy.pxi
==============================================================================
--- lxml/trunk/src/lxml/proxy.pxi (original)
+++ lxml/trunk/src/lxml/proxy.pxi Wed Sep 12 14:56:01 2007
@@ -102,26 +102,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
@@ -182,6 +162,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/trunk/src/lxml/serializer.pxi
==============================================================================
--- lxml/trunk/src/lxml/serializer.pxi (original)
+++ lxml/trunk/src/lxml/serializer.pxi Wed Sep 12 14:56:01 2007
@@ -79,14 +79,33 @@
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)
+
+ # copy the node and add namespaces from parents 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)
+
+ # 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)
More information about the lxml-checkins
mailing list