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.
This commit is contained in:
Andrew M. Kuchling 2000-12-20 14:47:24 +00:00
parent 34c20cf705
commit 04a45e9bb1
2 changed files with 42 additions and 10 deletions

View File

@ -40,6 +40,7 @@ class Node(_Node):
def __init__(self):
self.childNodes = []
self.parentNode = None
if Node._debug:
index = repr(id(self)) + repr(self.__class__)
Node.allnodes[index] = repr(self.__dict__)
@ -98,6 +99,8 @@ class Node(_Node):
return self.childNodes[-1]
def insertBefore(self, newChild, refChild):
if newChild.parentNode is not None:
newChild.parentNode.removeChild(newChild)
if refChild is None:
self.appendChild(newChild)
else:
@ -116,6 +119,8 @@ class Node(_Node):
return newChild
def appendChild(self, node):
if node.parentNode is not None:
node.parentNode.removeChild(node)
if self.childNodes:
last = self.lastChild
node.previousSibling = last
@ -129,6 +134,8 @@ class Node(_Node):
return node
def replaceChild(self, newChild, oldChild):
if newChild.parentNode is not None:
newChild.parentNode.removeChild(newChild)
if newChild is oldChild:
return
index = self.childNodes.index(oldChild)
@ -144,6 +151,12 @@ class Node(_Node):
def removeChild(self, oldChild):
self.childNodes.remove(oldChild)
if oldChild.nextSibling is not None:
oldChild.nextSibling.previousSibling = oldChild.previousSibling
if oldChild.previousSibling is not None:
oldChild.previousSibling.nextSibling = oldChild.nextSibling
oldChild.nextSibling = oldChild.previousSibling = None
if self._makeParentNodes:
oldChild.parentNode = None
return oldChild
@ -606,11 +619,23 @@ class Document(Node):
implementation = DOMImplementation()
def appendChild(self, node):
if node.parentNode is not None:
node.parentNode.removeChild(node)
if node.nodeType == Node.ELEMENT_NODE \
and self._get_documentElement():
raise TypeError, "two document elements disallowed"
return Node.appendChild(self, node)
def removeChild(self, oldChild):
self.childNodes.remove(oldChild)
oldChild.nextSibling = oldChild.previousSibling = None
oldChild.parentNode = None
if self.documentElement is oldChild:
self.documentElement = None
return oldChild
def _get_documentElement(self):
for node in self.childNodes:
if node.nodeType == Node.ELEMENT_NODE:

View File

@ -55,7 +55,9 @@ class PullDOM(xml.sax.ContentHandler):
attr.value = value
node.setAttributeNode(attr)
node.parentNode = self.curNode
## print self.curNode, self.curNode.childNodes, node, node.parentNode
self.curNode.appendChild(node)
# node.parentNode = self.curNode
self.curNode = node
self.lastEvent[1] = [(START_ELEMENT, node), None]
@ -77,7 +79,8 @@ class PullDOM(xml.sax.ContentHandler):
attr.value = value
node.setAttributeNode(attr)
node.parentNode = self.curNode
#node.parentNode = self.curNode
self.curNode.appendChild(node)
self.curNode = node
self.lastEvent[1] = [(START_ELEMENT, node), None]
@ -93,8 +96,9 @@ class PullDOM(xml.sax.ContentHandler):
def comment(self, s):
node = self.document.createComment(s)
parent = self.curNode
node.parentNode = parent
self.curNode.appendChild(node)
# parent = self.curNode
# node.parentNode = parent
self.lastEvent[1] = [(COMMENT, node), None]
self.lastEvent = self.lastEvent[1]
#self.events.append((COMMENT, node))
@ -102,24 +106,27 @@ class PullDOM(xml.sax.ContentHandler):
def processingInstruction(self, target, data):
node = self.document.createProcessingInstruction(target, data)
parent = self.curNode
node.parentNode = parent
self.curNode.appendChild(node)
# parent = self.curNode
# node.parentNode = parent
self.lastEvent[1] = [(PROCESSING_INSTRUCTION, node), None]
self.lastEvent = self.lastEvent[1]
#self.events.append((PROCESSING_INSTRUCTION, node))
def ignorableWhitespace(self, chars):
node = self.document.createTextNode(chars)
parent = self.curNode
node.parentNode = parent
self.curNode.appendChild(node)
# parent = self.curNode
# node.parentNode = parent
self.lastEvent[1] = [(IGNORABLE_WHITESPACE, node), None]
self.lastEvent = self.lastEvent[1]
#self.events.append((IGNORABLE_WHITESPACE, node))
def characters(self, chars):
node = self.document.createTextNode(chars)
parent = self.curNode
node.parentNode = parent
self.curNode.appendChild(node)
# parent = self.curNode
# node.parentNode = parent
self.lastEvent[1] = [(CHARACTERS, node), None]
self.lastEvent = self.lastEvent[1]