[XML-SIG] 4DOM: Problem cloning attributes

Alexandre Fayolle alexandre.fayolle@free.fr
Tue, 18 Jul 2000 18:48:46 +0200


Hello,

[I'm not sure a previous mail reporting a weird problem with importNode has made
it to the xml-sig list, since I have not received it myself. If so, this is a
narrowing of this problem]

I'm using 4Dom from the XML-SIG CVS repository.

I think I've found an issue on namespace when cloning attribute nodes. I have a
fix, but am not sure that it will work in all cases.

The problem is the following :

----------------------8<-------------------------------------------
from xml.dom.ext.reader import Sax2

tree = """<document><child foo='foo1' bar='bar1'/></document>"""

if __name__ == '__main__':
    doc = Sax2.FromXml(tree,None,0,1)

    child = doc.documentElement.firstChild
    print child
    clone = child.cloneNode(1)
    print clone
----------------------8<-------------------------------------------

The output of the script is :
[alf@leo alf]$ python domimport.py
<Element Node at 135922784: Name = 'child' with 2 attributes and 0 children>
<Element Node at 135910896: Name = 'child' with 1 attributes and 0
children>                                                               

I've lost an attribute during cloning.

By editing Attr.__repr__(), I've been able to notice the following changes
between the original attribute and the clone :
cloning attr <Attribute Node at 135896048: Name = "bar", Value = "bar1", Prefix
= "None", URI = "", LocalName = "bar">
cloned attr <Attribute Node at 135883704: Name = "bar", Value = "bar1", Prefix =
"", URI = "", LocalName = "">      

The prefix is changed from None to empty string, and the local name from 'bar'
to empty string.

This comes from Attr.cloneNode, where ownerDocument.createAttribute(self.name)
is used, instead of createAttributeNS(self.namespaceURI,self.name)

Therefore, I propose the following implementation for Attr.clone (inspired by
what is done in Element.cloneNode :

        def cloneNode(self, deep, node=None, newOwner=None):
        if node == None:
            if newOwner == None:
                if self.ownerDocument._4dom_isNsAware:
                    node =\
 self.ownerDocument.createAttributeNS(self.namespaceURI,self.name)
                else :
                    node = self.ownerDocument.createAttribute(self.name)
            else:
                if self.ownerDocument._4dom_isNsAware:
                    node =\
 newOwner.createAttributeNS(self.namespaceURI,self.name)
                else :
                    node = newOwner.createAttribute(self.name)
        #Clone from our ancestors
        Node.cloneNode(self, deep, node)
        return node
               

Alexandre Fayolle