[Python-bugs-list] [Bug #116677] minidom:Node.appendChild() has wrong semantics

noreply@sourceforge.net noreply@sourceforge.net
Tue, 21 Nov 2000 14:23:12 -0800


Bug #116677, was updated on 2000-Oct-11 19:24
Here is a current snapshot of the bug.

Project: Python
Category: Library
Status: Open
Resolution: None
Bug Group: None
Priority: 7
Summary: minidom:Node.appendChild() has wrong semantics

Details: Consider this test program:

from xml.dom import minidom
doc = minidom.Document()
root = doc.createElement('root') ; doc.appendChild( root )

elem = doc.createElement('leaf')
root.appendChild( elem )
root.appendChild( elem )

print doc.toxml()
print root.childNodes

It prints:
<root><leaf/><leaf/></root>
[<DOM Element: leaf at 135586476>, <DOM Element: leaf at 135586476>]

'elem' is now linked into the DOM tree in two places, which is wrong; according to the DOM Level 1 spec, 
"If the newChild is already in the tree, it is first removed."



Follow-Ups:

Date: 2000-Oct-11 19:55
By: fdrake

Comment:
Andrew:  Are you using 2.0c1 or CVS?
-------------------------------------------------------

Date: 2000-Oct-11 20:11
By: akuchling

Comment:
CVS as of this evening.  Did it work before?

(Hmm... tonight test_minidom is failing for me for some reason.  
Wonder if it's related?)
-------------------------------------------------------

Date: 2000-Oct-12 07:37
By: Nobody

Comment:
The test_minidom failure turned out to be caused by something else.  However, I rechecked my test case and it's still broken with tonight's CVS.
-------------------------------------------------------

Date: 2000-Oct-16 00:43
By: loewis

Comment:
This is indeed a bug in minidom, but I don't think it should be corrected for 2.0; I suggest to reduce the priority of it, or close it as "later".

While this is a deviation from the DOM spec, it seems as a border case. As such, it should be documented; users can always explicitly remove the node before appending it elsewhere.
-------------------------------------------------------

Date: 2000-Oct-16 06:47
By: akuchling

Comment:
I don't see why this particular deviation is a border case.
All the methods for modifying a DOM tree -- appendChild(),
insertBefore(), replaceChild() -- all behave the same way,
first removing the added node if it's already in the tree somewhere.  This will make it more difficult to translate DOM-using code from, say, Java, to Python + minidom, since you'll have to remember to add extra .removeChild() calls.
Worse still, the problems caused by this will be hard to track down; portions of your DOM tree are aliased, but .toxml() won't make this clear.
-------------------------------------------------------

Date: 2000-Nov-21 14:23
By: fdrake

Comment:
Re-categorized this bug to "XML".

This is *not* fixed by Lib/xml/dom/minidom.py revision 1.14.

Unfortunately, this bug will be a little harder to fix.  I looked to see if I could determine presence in the tree by checking for parentNode != None, but that isn't sufficient.  xml.dom.pulldom maintains state by filling in the parentNode attribute, so it has a chain of ancestors; it needs this to find the node to add children to in DOMEventStream.expandNode().  Testing that a node is already in the tree is harder, but not much harder.  A reasonable fix for this bug should not be difficult.
-------------------------------------------------------

For detailed info, follow this link:
http://sourceforge.net/bugs/?func=detailbug&bug_id=116677&group_id=5470