I am new to XPath, and from what I have read in some tutorials about axes, I am still left wondering how to implement them. They aren't quite behaving as I had expected. I am particularly interested in using ancestor and descendant axes.
I have the following XML structure:
<file>
<criteria>
<root>ROOT</root>
<criterion>AAA</criterion>
<criterion>BBB</criterion>
<criterion>CCC</criterion>
</criteria>
<format>
<sort>BBB</sort>
</format>
</file>
And I have the following XSL:
<xsl:template match="/">
<xsl:copy-of select="ancestor::criterion/>
</xsl:template>
which produces nothing!
I expected it to produce:
<file>
<criteria>
</criteria>
</file>
Can someone explain ancestor and descendant axes to me in a more helpful way than the tutorials I have previously read?
Thanks!
And I have the following XSL:
<xsl:template match="/"> <xsl:copy-of select="ancestor::criterion/> </xsl:template>
which produces nothing!
As it should!
ancestor::criterion
is a relative expression, which means that it is evaluated off the current node (matched by the template). But the current node is the document node /
.
So, the above is equivalent to:
/ancestor::criterion
However, by definition the document node /
has no parents (and that means no ancestors), so this XPath expression doesn't select any node.
I expected it to produce:
<file> <criteria> </criteria> </file>
What you probably wanted was:
//criterion/ancestor::*
or
//*[descendant::criterion]
The last two XPath expressions are equivalent and select all elements that have a criterion
descendant.
Finally, to produce the output you wanted, here is one possible solution:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root | criterion | format"/>
</xsl:stylesheet>
When this transformation is applied on the provided XML document, the wanted output is produced:
<file>
<criteria>
</criteria>
</file>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With