Commit 04a45e9b authored by Andrew M. Kuchling's avatar Andrew M. Kuchling

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.
parent 34c20cf7
...@@ -40,6 +40,7 @@ class Node(_Node): ...@@ -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 @@ class Node(_Node): ...@@ -98,6 +99,8 @@ class Node(_Node):
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 @@ class Node(_Node): ...@@ -116,6 +119,8 @@ class Node(_Node):
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 @@ class Node(_Node): ...@@ -129,6 +134,8 @@ class Node(_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 @@ class Node(_Node): ...@@ -144,6 +151,12 @@ class Node(_Node):
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): ...@@ -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:
......
...@@ -55,7 +55,9 @@ class PullDOM(xml.sax.ContentHandler): ...@@ -55,7 +55,9 @@ class PullDOM(xml.sax.ContentHandler):
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 @@ class PullDOM(xml.sax.ContentHandler): ...@@ -77,7 +79,8 @@ class PullDOM(xml.sax.ContentHandler):
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 @@ class PullDOM(xml.sax.ContentHandler): ...@@ -93,8 +96,9 @@ class PullDOM(xml.sax.ContentHandler):
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 @@ class PullDOM(xml.sax.ContentHandler): ...@@ -102,24 +106,27 @@ class PullDOM(xml.sax.ContentHandler):
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]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment