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

Alexandre CONRAD aconrad.tlv at magic.fr
Thu Aug 5 18:21:41 CEST 2004



xmlsig at codeweld.com wrote:

> 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

Ur da man !! :D

I fixed the prob on my side but was doing a dirty trick :

if parent.nodeName == node.nodeName and parent.nodeName != 
node.ownerDocument.firstChild.nodeName: successors += 1

Uuugh ! I don't like that. I feel better that you have found the 
solution. Don't like to know there's dirty code in my application. ;)

Thank you so much for your help. That's a great function to be able to 
build the xpath of a given node.

Very 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



More information about the XML-SIG mailing list