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

View File

@ -55,7 +55,9 @@ def startElementNS(self, name, tagName , attrs):
attr.value = value attr.value = value
node.setAttributeNode(attr) 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.curNode = node
self.lastEvent[1] = [(START_ELEMENT, node), None] self.lastEvent[1] = [(START_ELEMENT, node), None]
@ -77,7 +79,8 @@ def startElement(self, name, attrs):
attr.value = value attr.value = value
node.setAttributeNode(attr) node.setAttributeNode(attr)
node.parentNode = self.curNode #node.parentNode = self.curNode
self.curNode.appendChild(node)
self.curNode = node self.curNode = node
self.lastEvent[1] = [(START_ELEMENT, node), None] self.lastEvent[1] = [(START_ELEMENT, node), None]
@ -93,8 +96,9 @@ def endElement(self, name):
def comment(self, s): def comment(self, s):
node = self.document.createComment(s) node = self.document.createComment(s)
parent = self.curNode self.curNode.appendChild(node)
node.parentNode = parent # parent = self.curNode
# node.parentNode = parent
self.lastEvent[1] = [(COMMENT, node), None] self.lastEvent[1] = [(COMMENT, node), None]
self.lastEvent = self.lastEvent[1] self.lastEvent = self.lastEvent[1]
#self.events.append((COMMENT, node)) #self.events.append((COMMENT, node))
@ -102,24 +106,27 @@ def comment(self, s):
def processingInstruction(self, target, data): def processingInstruction(self, target, data):
node = self.document.createProcessingInstruction(target, data) node = self.document.createProcessingInstruction(target, data)
parent = self.curNode self.curNode.appendChild(node)
node.parentNode = parent # parent = self.curNode
# node.parentNode = parent
self.lastEvent[1] = [(PROCESSING_INSTRUCTION, node), None] self.lastEvent[1] = [(PROCESSING_INSTRUCTION, node), None]
self.lastEvent = self.lastEvent[1] self.lastEvent = self.lastEvent[1]
#self.events.append((PROCESSING_INSTRUCTION, node)) #self.events.append((PROCESSING_INSTRUCTION, node))
def ignorableWhitespace(self, chars): def ignorableWhitespace(self, chars):
node = self.document.createTextNode(chars) node = self.document.createTextNode(chars)
parent = self.curNode self.curNode.appendChild(node)
node.parentNode = parent # parent = self.curNode
# node.parentNode = parent
self.lastEvent[1] = [(IGNORABLE_WHITESPACE, node), None] self.lastEvent[1] = [(IGNORABLE_WHITESPACE, node), None]
self.lastEvent = self.lastEvent[1] self.lastEvent = self.lastEvent[1]
#self.events.append((IGNORABLE_WHITESPACE, node)) #self.events.append((IGNORABLE_WHITESPACE, node))
def characters(self, chars): def characters(self, chars):
node = self.document.createTextNode(chars) node = self.document.createTextNode(chars)
parent = self.curNode self.curNode.appendChild(node)
node.parentNode = parent # parent = self.curNode
# node.parentNode = parent
self.lastEvent[1] = [(CHARACTERS, node), None] self.lastEvent[1] = [(CHARACTERS, node), None]
self.lastEvent = self.lastEvent[1] self.lastEvent = self.lastEvent[1]