Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 04a45e9

Browse files
committed
Patch #102492, fixing bug #116677:
give minidom.py behaviour that complies with the DOM Level 1 REC, which says that when a node newChild is added to the tree, "if the newChild is already in the tree, it is first removed." pulldom.py is patched to use the public minidom interface instead of setting .parentNode itself. Possibly this reduces pulldom's efficiency; someone else will have to pronounce on that.
1 parent 34c20cf commit 04a45e9

2 files changed

Lines changed: 42 additions & 10 deletions

File tree

Lib/xml/dom/minidom.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class Node(_Node):
4040

4141
def __init__(self):
4242
self.childNodes = []
43+
self.parentNode = None
4344
if Node._debug:
4445
index = repr(id(self)) + repr(self.__class__)
4546
Node.allnodes[index] = repr(self.__dict__)
@@ -98,6 +99,8 @@ def _get_lastChild(self):
9899
return self.childNodes[-1]
99100

100101
def insertBefore(self, newChild, refChild):
102+
if newChild.parentNode is not None:
103+
newChild.parentNode.removeChild(newChild)
101104
if refChild is None:
102105
self.appendChild(newChild)
103106
else:
@@ -116,6 +119,8 @@ def insertBefore(self, newChild, refChild):
116119
return newChild
117120

118121
def appendChild(self, node):
122+
if node.parentNode is not None:
123+
node.parentNode.removeChild(node)
119124
if self.childNodes:
120125
last = self.lastChild
121126
node.previousSibling = last
@@ -129,6 +134,8 @@ def appendChild(self, node):
129134
return node
130135

131136
def replaceChild(self, newChild, oldChild):
137+
if newChild.parentNode is not None:
138+
newChild.parentNode.removeChild(newChild)
132139
if newChild is oldChild:
133140
return
134141
index = self.childNodes.index(oldChild)
@@ -144,6 +151,12 @@ def replaceChild(self, newChild, oldChild):
144151

145152
def removeChild(self, oldChild):
146153
self.childNodes.remove(oldChild)
154+
if oldChild.nextSibling is not None:
155+
oldChild.nextSibling.previousSibling = oldChild.previousSibling
156+
if oldChild.previousSibling is not None:
157+
oldChild.previousSibling.nextSibling = oldChild.nextSibling
158+
oldChild.nextSibling = oldChild.previousSibling = None
159+
147160
if self._makeParentNodes:
148161
oldChild.parentNode = None
149162
return oldChild
@@ -606,11 +619,23 @@ class Document(Node):
606619
implementation = DOMImplementation()
607620

608621
def appendChild(self, node):
622+
if node.parentNode is not None:
623+
node.parentNode.removeChild(node)
624+
609625
if node.nodeType == Node.ELEMENT_NODE \
610626
and self._get_documentElement():
611627
raise TypeError, "two document elements disallowed"
612628
return Node.appendChild(self, node)
613629

630+
def removeChild(self, oldChild):
631+
self.childNodes.remove(oldChild)
632+
oldChild.nextSibling = oldChild.previousSibling = None
633+
oldChild.parentNode = None
634+
if self.documentElement is oldChild:
635+
self.documentElement = None
636+
637+
return oldChild
638+
614639
def _get_documentElement(self):
615640
for node in self.childNodes:
616641
if node.nodeType == Node.ELEMENT_NODE:

Lib/xml/dom/pulldom.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ def startElementNS(self, name, tagName , attrs):
5555
attr.value = value
5656
node.setAttributeNode(attr)
5757

58-
node.parentNode = self.curNode
58+
## print self.curNode, self.curNode.childNodes, node, node.parentNode
59+
self.curNode.appendChild(node)
60+
# node.parentNode = self.curNode
5961
self.curNode = node
6062

6163
self.lastEvent[1] = [(START_ELEMENT, node), None]
@@ -77,7 +79,8 @@ def startElement(self, name, attrs):
7779
attr.value = value
7880
node.setAttributeNode(attr)
7981

80-
node.parentNode = self.curNode
82+
#node.parentNode = self.curNode
83+
self.curNode.appendChild(node)
8184
self.curNode = node
8285

8386
self.lastEvent[1] = [(START_ELEMENT, node), None]
@@ -93,33 +96,37 @@ def endElement(self, name):
9396

9497
def comment(self, s):
9598
node = self.document.createComment(s)
96-
parent = self.curNode
97-
node.parentNode = parent
99+
self.curNode.appendChild(node)
100+
# parent = self.curNode
101+
# node.parentNode = parent
98102
self.lastEvent[1] = [(COMMENT, node), None]
99103
self.lastEvent = self.lastEvent[1]
100104
#self.events.append((COMMENT, node))
101105

102106
def processingInstruction(self, target, data):
103107
node = self.document.createProcessingInstruction(target, data)
104108

105-
parent = self.curNode
106-
node.parentNode = parent
109+
self.curNode.appendChild(node)
110+
# parent = self.curNode
111+
# node.parentNode = parent
107112
self.lastEvent[1] = [(PROCESSING_INSTRUCTION, node), None]
108113
self.lastEvent = self.lastEvent[1]
109114
#self.events.append((PROCESSING_INSTRUCTION, node))
110115

111116
def ignorableWhitespace(self, chars):
112117
node = self.document.createTextNode(chars)
113-
parent = self.curNode
114-
node.parentNode = parent
118+
self.curNode.appendChild(node)
119+
# parent = self.curNode
120+
# node.parentNode = parent
115121
self.lastEvent[1] = [(IGNORABLE_WHITESPACE, node), None]
116122
self.lastEvent = self.lastEvent[1]
117123
#self.events.append((IGNORABLE_WHITESPACE, node))
118124

119125
def characters(self, chars):
120126
node = self.document.createTextNode(chars)
121-
parent = self.curNode
122-
node.parentNode = parent
127+
self.curNode.appendChild(node)
128+
# parent = self.curNode
129+
# node.parentNode = parent
123130
self.lastEvent[1] = [(CHARACTERS, node), None]
124131
self.lastEvent = self.lastEvent[1]
125132

0 commit comments

Comments
 (0)