CodeUp

Feeling the byte

Get XPath of one element in XSLT

leave a comment

Here is the code to get all XPath trees of all elements of given XML document. You can easily change the code to get a single node’s XPath.

?Download xpath.xsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="text"/>
 
	<xsl:template match="*" mode="get-xpath">
		<xsl:apply-templates select="parent::*" mode="get-xpath"/>
 
		<xsl:text>/</xsl:text><xsl:value-of select="name()"/>
		<xsl:if test="../*[2]">
			<xsl:text>[</xsl:text>
			<xsl:value-of select="1+count(preceding-sibling::*[name(.)=name(current())])"/>
			<xsl:text>]</xsl:text>
		</xsl:if>
	</xsl:template>
 
	<xsl:template match="@*" mode="get-xpath">
		<xsl:apply-templates select="parent::*" mode="get-xpath"/>
 
		<xsl:text>/@</xsl:text>
 
		<xsl:choose>
			<xsl:when test="namespace-uri() = ''">
				<xsl:value-of select="name()"/>
				<!--<xsl:text> = <xsl:value-of select="."/></xsl:text>-->
			</xsl:when>
			<xsl:otherwise>
				<xsl:text>*[local-name()='</xsl:text>
				<xsl:value-of select="local-name()"/>
				<xsl:text>' and namespace-uri()='</xsl:text>
				<xsl:value-of select="namespace-uri()"/>
				<xsl:text>']</xsl:text>
				<!--<xsl:text> = <xsl:value-of select="."/></xsl:text>-->
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
 
	<xsl:template match="/">
		<xsl:for-each select="//*|//*/@*">
			<xsl:apply-templates mode="get-xpath" select="."/><xsl:text>
</xsl:text>
		</xsl:for-each>
	</xsl:template>
 
</xsl:stylesheet>

If you try to transform this example XML document …

?Download example.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<books>
	<book isbn="0130353132">
		<title>Thinking in C++, Volume 2: Practical Programming</title>
		<author>Bruce Eckel</author>
		<pages>832</pages>
	</book>
	<book isbn="0385504225">
		<title>The Lost Symbol</title>
		<author>Dan Brown</author>
		<pages>528</pages>
	</book>
	<book isbn="0307454541">
		<title>The Girl with the Dragon Tattoo</title>
		<author>Stieg Larsson</author>
		<pages>608</pages>
	</book>
</books>

.. you’ll got all expanded tree of XPaths (as expected :) )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/books
/books/book[1]
/books/book[1]/@isbn
/books/book[1]/title[1]
/books/book[1]/author[1]
/books/book[1]/pages[1]
/books/book[2]
/books/book[2]/@isbn
/books/book[2]/title[1]
/books/book[2]/author[1]
/books/book[2]/pages[1]
/books/book[3]
/books/book[3]/@isbn
/books/book[3]/title[1]
/books/book[3]/author[1]
/books/book[3]/pages[1]

Written by Moisés Maciá

January 7th, 2010 at 1:39 pm

Posted in Recipes

Tagged with , , ,