[Lxml-checkins] r54340 - in lxml/trunk: . src/lxml
scoder at codespeak.net
scoder at codespeak.net
Fri May 2 19:14:58 CEST 2008
Author: scoder
Date: Fri May 2 19:14:57 2008
New Revision: 54340
Modified:
lxml/trunk/ (props changed)
lxml/trunk/src/lxml/apihelpers.pxi
lxml/trunk/src/lxml/lxml.etree.pyx
lxml/trunk/src/lxml/proxy.pxi
lxml/trunk/src/lxml/tree.pxd
Log:
r4119 at delle: sbehnel | 2008-05-02 18:10:34 +0200
re-assign all node name pointers from the target dictionary when moving an element to a new tree of a different thread
Modified: lxml/trunk/src/lxml/apihelpers.pxi
==============================================================================
--- lxml/trunk/src/lxml/apihelpers.pxi (original)
+++ lxml/trunk/src/lxml/apihelpers.pxi Fri May 2 19:14:57 2008
@@ -716,7 +716,7 @@
_moveTail(c_next, c_node)
if not attemptDeallocation(c_node):
# make namespaces absolute
- moveNodeToDocument(doc, c_node)
+ moveNodeToDocument(doc, c_node.doc, c_node)
return 0
cdef void _moveTail(xmlNode* c_tail, xmlNode* c_target):
@@ -782,6 +782,7 @@
"""
cdef xmlNode* c_orig_neighbour
cdef xmlNode* c_next
+ cdef xmlDoc* c_source_doc
cdef _Element element
cdef Py_ssize_t seqlength, i, c
cdef _node_to_node_function next_element
@@ -864,12 +865,13 @@
for element in elements:
assert element is not None, "Node must not be None"
# move element and tail over
+ c_source_doc = element._c_node.doc
c_next = element._c_node.next
tree.xmlAddPrevSibling(c_node, element._c_node)
_moveTail(c_next, element._c_node)
# integrate element into new document
- moveNodeToDocument(parent._doc, element._c_node)
+ moveNodeToDocument(parent._doc, c_source_doc, element._c_node)
# stop at the end of the slice
if slicelength > 0:
@@ -899,7 +901,9 @@
"""
cdef xmlNode* c_next
cdef xmlNode* c_node
+ cdef xmlDoc* c_source_doc
c_node = child._c_node
+ c_source_doc = c_node.doc
# store possible text node
c_next = c_node.next
# move node itself
@@ -908,7 +912,7 @@
_moveTail(c_next, c_node)
# uh oh, elements may be pointing to different doc when
# parent element has moved; change them too..
- moveNodeToDocument(parent._doc, c_node)
+ moveNodeToDocument(parent._doc, c_source_doc, c_node)
cdef int _prependChild(_Element parent, _Element child) except -1:
"""Prepend a new child to a parent element.
@@ -916,7 +920,9 @@
cdef xmlNode* c_next
cdef xmlNode* c_child
cdef xmlNode* c_node
+ cdef xmlDoc* c_source_doc
c_node = child._c_node
+ c_source_doc = c_node.doc
# store possible text node
c_next = c_node.next
# move node itself
@@ -929,14 +935,16 @@
_moveTail(c_next, c_node)
# uh oh, elements may be pointing to different doc when
# parent element has moved; change them too..
- moveNodeToDocument(parent._doc, c_node)
+ moveNodeToDocument(parent._doc, c_source_doc, c_node)
cdef int _appendSibling(_Element element, _Element sibling) except -1:
"""Append a new child to a parent element.
"""
cdef xmlNode* c_next
cdef xmlNode* c_node
+ cdef xmlDoc* c_source_doc
c_node = sibling._c_node
+ c_source_doc = c_node.doc
# store possible text node
c_next = c_node.next
# move node itself
@@ -944,14 +952,16 @@
_moveTail(c_next, c_node)
# uh oh, elements may be pointing to different doc when
# parent element has moved; change them too..
- moveNodeToDocument(element._doc, c_node)
+ moveNodeToDocument(element._doc, c_source_doc, c_node)
cdef int _prependSibling(_Element element, _Element sibling) except -1:
"""Append a new child to a parent element.
"""
cdef xmlNode* c_next
cdef xmlNode* c_node
+ cdef xmlDoc* c_source_doc
c_node = sibling._c_node
+ c_source_doc = c_node.doc
# store possible text node
c_next = c_node.next
# move node itself
@@ -959,7 +969,7 @@
_moveTail(c_next, c_node)
# uh oh, elements may be pointing to different doc when
# parent element has moved; change them too..
- moveNodeToDocument(element._doc, c_node)
+ moveNodeToDocument(element._doc, c_source_doc, c_node)
cdef inline int isutf8(char* s):
cdef char c
Modified: lxml/trunk/src/lxml/lxml.etree.pyx
==============================================================================
--- lxml/trunk/src/lxml/lxml.etree.pyx (original)
+++ lxml/trunk/src/lxml/lxml.etree.pyx Fri May 2 19:14:57 2008
@@ -533,6 +533,7 @@
"""
cdef xmlNode* c_node
cdef xmlNode* c_next
+ cdef xmlDoc* c_source_doc
cdef _Element element
cdef bint left_to_right
cdef Py_ssize_t slicelength, step
@@ -554,13 +555,14 @@
c_node = _findChild(self._c_node, x)
if c_node is NULL:
raise IndexError, "list index out of range"
+ c_source_doc = element._c_node.doc
c_next = element._c_node.next
_removeText(c_node.next)
tree.xmlReplaceNode(c_node, element._c_node)
_moveTail(c_next, element._c_node)
- moveNodeToDocument(self._doc, element._c_node)
+ moveNodeToDocument(self._doc, c_source_doc, element._c_node)
if not attemptDeallocation(c_node):
- moveNodeToDocument(self._doc, c_node)
+ moveNodeToDocument(self._doc, c_node.doc, c_node)
def __delitem__(self, x):
"""__delitem__(self, x)
@@ -707,14 +709,16 @@
"""
cdef xmlNode* c_node
cdef xmlNode* c_next
+ cdef xmlDoc* c_source_doc
c_node = _findChild(self._c_node, index)
if c_node is NULL:
_appendChild(self, element)
return
+ c_source_doc = c_node.doc
c_next = element._c_node.next
tree.xmlAddPrevSibling(c_node, element._c_node)
_moveTail(c_next, element._c_node)
- moveNodeToDocument(self._doc, element._c_node)
+ moveNodeToDocument(self._doc, c_source_doc, element._c_node)
def remove(self, _Element element not None):
"""remove(self, element)
@@ -732,7 +736,7 @@
tree.xmlUnlinkNode(c_node)
_moveTail(c_next, c_node)
# fix namespace declarations
- moveNodeToDocument(self._doc, c_node)
+ moveNodeToDocument(self._doc, c_node.doc, c_node)
def replace(self, _Element old_element not None,
_Element new_element not None):
@@ -744,18 +748,20 @@
cdef xmlNode* c_old_next
cdef xmlNode* c_new_node
cdef xmlNode* c_new_next
+ cdef xmlDoc* c_source_doc
c_old_node = old_element._c_node
if c_old_node.parent is not self._c_node:
raise ValueError, "Element is not a child of this node."
c_old_next = c_old_node.next
c_new_node = new_element._c_node
c_new_next = c_new_node.next
+ c_source_doc = c_new_next.doc
tree.xmlReplaceNode(c_old_node, c_new_node)
_moveTail(c_new_next, c_new_node)
_moveTail(c_old_next, c_old_node)
- moveNodeToDocument(self._doc, c_new_node)
+ moveNodeToDocument(self._doc, c_source_doc, c_new_node)
# fix namespace declarations
- moveNodeToDocument(self._doc, c_old_node)
+ moveNodeToDocument(self._doc, c_old_node.doc, c_old_node)
# PROPERTIES
property tag:
Modified: lxml/trunk/src/lxml/proxy.pxi
==============================================================================
--- lxml/trunk/src/lxml/proxy.pxi (original)
+++ lxml/trunk/src/lxml/proxy.pxi Fri May 2 19:14:57 2008
@@ -276,7 +276,8 @@
c_nsdef[0] = c_ns_next
return 0
-cdef int moveNodeToDocument(_Document doc, xmlNode* c_element) except -1:
+cdef int moveNodeToDocument(_Document doc, xmlDoc* c_source_doc,
+ xmlNode* c_element) except -1:
"""Fix the xmlNs pointers of a node and its subtree that were moved.
Mainly copied from libxml2's xmlReconciliateNs(). Expects libxml2 doc
@@ -293,7 +294,11 @@
prefix). If a namespace is unknown, declare a new one on the
node.
- 3) Set the Document reference to the new Document (if different).
+ 3) Reassign the names of tags and attribute from the dict of the
+ target document *iff* it is different from the dict used in the
+ source subtree.
+
+ 4) Set the Document reference to the new Document (if different).
This is done on backtracking to keep the original Document
alive as long as possible, until all its elements are updated.
@@ -303,16 +308,26 @@
"""
cdef xmlNode* c_start_node
cdef xmlNode* c_node
+ cdef char* c_name
cdef _nscache c_ns_cache
cdef xmlNs* c_ns
cdef xmlNs* c_ns_next
cdef xmlNs* c_nsdef
cdef xmlNs* c_del_ns_list
cdef cstd.size_t i
+ cdef tree.xmlDict* c_dict
if not tree._isElementOrXInclude(c_element):
return 0
+ # we need to copy the names of tags and attributes iff the element
+ # is based on a different libxml2 tag name dictionary
+ if doc._c_doc.dict is not c_source_doc.dict and \
+ doc._c_doc.dict is not NULL and c_source_doc.dict is not NULL:
+ c_dict = doc._c_doc.dict
+ else:
+ c_dict = NULL
+
c_start_node = c_element
c_del_ns_list = NULL
@@ -343,6 +358,13 @@
c_element, c_node.ns.href, c_node.ns.prefix)
_appendToNsCache(&c_ns_cache, c_node.ns, c_ns)
c_node.ns = c_ns
+
+ # 3) re-assign names from the target dict
+ if c_dict is not NULL:
+ c_name = tree.xmlDictLookup(c_dict, c_node.name, -1)
+ if c_name is not NULL:
+ c_element.name = c_name
+
if c_node is c_element:
# after the element, continue with its attributes
c_node = <xmlNode*>c_element.properties
@@ -358,7 +380,7 @@
if c_node is NULL:
# no children => back off and continue with siblings and parents
- # 3) fix _Document reference (may dealloc the original document!)
+ # 4) fix _Document reference (may dealloc the original document!)
if c_element._private is not NULL:
_updateProxyDocument(c_element, doc)
@@ -376,7 +398,7 @@
if c_element is NULL or not tree._isElementOrXInclude(c_element):
break
- # 3) fix _Document reference (may dealloc the original document!)
+ # 4) fix _Document reference (may dealloc the original document!)
if c_element._private is not NULL:
_updateProxyDocument(c_element, doc)
Modified: lxml/trunk/src/lxml/tree.pxd
==============================================================================
--- lxml/trunk/src/lxml/tree.pxd (original)
+++ lxml/trunk/src/lxml/tree.pxd Fri May 2 19:14:57 2008
@@ -52,12 +52,12 @@
void xmlHashScan(xmlHashTable* table, xmlHashScanner f, void* data) nogil
void* xmlHashLookup(xmlHashTable* table, char* name) nogil
-cdef extern from "libxml/tree.h":
-
- # for some reason need to define this in this section;
+cdef extern from *: # actually "libxml/dict.h"
# libxml/dict.h appears to be broken to include in C
ctypedef struct xmlDict
-
+ cdef char* xmlDictLookup(xmlDict* dict, char* name, int len)
+
+cdef extern from "libxml/tree.h":
ctypedef struct xmlDoc
ctypedef struct xmlAttr
ctypedef struct xmlNotationTable
More information about the lxml-checkins
mailing list