[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] better way to get the path to a node?


Subject: Re: [xsl] better way to get the path to a node?
From: David Carlisle <davidc@xxxxxxxxx>
Date: Sat, 01 Dec 2012 12:05:47 +0000

On 01/12/2012 02:52, Graydon wrote:
Greetings --

If I want to return the XPath path to a specific node when that node is
the context node, is there a better way than:

<xsl:sequence
select="string-join(ancestor-or-self::*/concat('/',name(),'[',for $x in . return count(preceding-sibling::*[name() eq $x/name()])+1,']'),'')"/>

"Better" here means "more efficient"; I'll be using various Saxon 9.*
for this, either in oXygen or from java.


As has been mentioned, saxon has an extension for this if you have saxon extensions.

For XSLT implementations, the schematron sources have several versions depending on the use case.

Using name() as you have it makes for a more human readable path but relies on the namespace prefixes in the current source being the same as in the context where the xpath will be evaluated, which isn't always the case.

Instead of generating
/h:html[1]/h:body[1]/m:math[1]

you can generate

/*[local-name()='html' and namespace-uri()='http://www.w3.org/1999/xhtml'][1]/
/*[local-name()='body' and namespace-uri()='http://www.w3.org/1999/xhtml'][1]/
/*[local-name()='math' and namespace-uri()='http://www.w3.org/1998/Math/MathML'][1]


which doesn't rely on h and m being bound.

In XPath3 draft you'd be able to use the new EQName thingy to make that a bit more readable.

Simpler and avoiding namespace woes is to generate

/*[1]/*[2]/*[23]

ie just count elements without regard for name, This works of course but doesn't give a human reader of the xpath much of a clue what was being identified.


David



h:body[1]/m:math[1]



-- google plus: https:/profiles.google.com/d.p.carlisle


Current Thread
Keywords