[XML-SIG] get the abolute path for a node

xmlsig at codeweld.com xmlsig at codeweld.com
Thu Aug 5 17:29:38 CEST 2004


Quoting Alexandre CONRAD <aconrad.tlv at magic.fr>:

> > Does this help?
> >
> > def abs_path( node ):
> >     successors = 1
> >     parent = node.previousSibling
> >     while parent:
> >         if parent.nodeName == node.nodeName: successors += 1
> >         parent = parent.previousSibling
> >     name = node.nodeName == '#text' and 'text()' or node.nodeName
> >     path = successors>1 and '/%s[%s]'%(name,successors) or '/%s'%name
> >     if node.parentNode and node.parentNode.nodeName != '#document':
> >         return abs_path( node.parentNode )+path
> >     return path
>
>
> Because I always strip out spaces in XML documents, and because I want
> to show the 1st node with node[1], I changed your code so:
>
> - name = node.nodeName == '#text' and 'text()' or node.nodeName
> - path = successors>1 and '/%s[%s]'%(name,successors) or '/%s'%name
> + path = '/%s[%s]' % (node.nodeName, successors)
>
>
> This is function is pretty neat. But still, there is 1 more little thing
> that I'm having a hard time figuring out how to fix. I keep getting
> "/playlist[2]" as the root node. I can't have 2 root nodes anyway...
>
> <?xml version='1.0' encoding='UTF-8'?>
> <playlist>
>    <group> <-- shows: /playlist[2]/group[1]
>      <video>foo.mpg</video> <-- shows: /playlist[2]/group[1]/video[1]
>      <video>bar.mpg</video> <-- shows: /playlist[2]/group[1]/video[2]
>    </group>
> </playlist>
>
> And this looping code inside the function everytime makes me loose track
> of what's doing on. Well done though.
>
> Best regards,
> --
> Alexandre CONRAD - TLV
> Research & Development
> tel : +33 1 30 80 55 05
> fax : +33 1 30 56 55 06
> 6, rue de la plaine
> 78860 - SAINT NOM LA BRETECHE
> FRANCE

The line that ranslates '#text' to 'text()' has the advantage that it translates
the path to a valid xpath the other line that eliminates [1] still preserves
this valid xpath, and I thought it's nicer to look at :).
I found the source and the cure of the problem. The source is ( as you can
easely verify with http://www.codeweld.com/files/dom_view.pyw, just use
'file://yourfile.xml' ) that the Sax2 reader for some reason puts a second node
with the same nodeName in. The cure is to take for comparision the localName, as
this name seems to be different for those. Additionaly he's also different for
some other nodes which might otherwise in border situations made trouble. This
is the new function. ( I also gave one variable a more reasonable name, was
confusing otherwise )

def abs_path( node ):
    successors = 1
    previous = node.previousSibling
    while previous:
        if previous.localName == node.localName: successors += 1
        previous = previous.previousSibling
    path = '/%s[%s]' % (node.nodeName, successors)
    if node.parentNode.nodeName != '#document':
        return abs_path( node.parentNode )+path
    return path

Kind Regards
Florian


More information about the XML-SIG mailing list