Here is an XSLT solution that produces the XPATH expressions for each of the inner-most elements.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<!--Match on all elements that do not contain child elements -->
<xsl:template match="//*[not(*)]">
<!--look up the node tree and write out:
- a slash
- the name of the element
- and a predicate filter for the position of the element at each step -->
<xsl:for-each select="ancestor-or-self::*">
<xsl:text>/</xsl:text>
<xsl:value-of select="local-name()"/>
<!--add a predicate filter to specify the position, in case there are more than one element with that name at that step -->
<xsl:text>[</xsl:text>
<xsl:value-of select="count(preceding-sibling::*[name()=name(current())])+1" />
<xsl:text>]</xsl:text>
</xsl:for-each>
<!--Create a new line after ever element -->
<xsl:text>
</xsl:text>
</xsl:template>
<!--override default template to prevent extra whitespace and carriage return from being copied into the output-->
<xsl:template match="text()" />
</xsl:stylesheet>
I added predicate filters to specify the position of the element. That way, if you had more than one piece
or itemc
element at the same level, the XPATH would specify the correct one.
So, instead of:
items/item1/piece
items/item1/itemc
items/item2/piece
items/item2/itemc
it produces:
/items[1]/item1[1]/piece[1]
/items[1]/item1[1]/itemc[1]
/items[1]/item2[1]/piece[1]
/items[1]/item2[1]/itemc[1]