XSLT 2.0 offers the benefit of passing a node-set param as part of the position() function. Unfortunately, that is not available in XSLT 1.0. Is there a way to mimic this behavior?
For example, given this XML:
<wishlists>
<wishlist name="Games">
<product name="Crash Bandicoot"/>
<product name="Super Mario Brothers"/>
<product name="Sonic the Hedgehog"/>
</wishlist>
<wishlist name="Movies">
<product name="Back to the Future"/>
</wishlist>
</wishlists>
and this XSLT 2.0:
<xsl:value-of select="position(/wishlists/wishlist/product)"/>
the value "4" would be returned when processing the final "Back to the Future" node.
Unfortunately, the closest I seem to be able to get with XSLT 1.0 is the following:
<xsl:template match="product">
<xsl:value-of select="position()"/>
</xsl:template>
However, I would get a value of "1" in the same "Back to the Future" node, as opposed to the "4" value that I really want.
You can use the preceding axis .
This XSLT 1.0 stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="product">
<product position="{count(preceding::product) + 1}">
<xsl:apply-templates select="@*"/>
</product>
</xsl:template>
</xsl:stylesheet>
Applied to your XML input produces:
<wishlists>
<wishlist name="Games">
<product position="1" name="Crash Bandicoot"/>
<product position="2" name="Super Mario Brothers"/>
<product position="3" name="Sonic the Hedgehog"/>
</wishlist>
<wishlist name="Movies">
<product position="4" name="Back to the Future"/>
</wishlist>
</wishlists>
XSLT 2.0 offers the benefit of passing a node-set param as part of the position() function.
This statement is wrong. The position()
function has no arguments -- either in XPath 1.0 or in XPath 2.0, which XSLT 2.0 uses.
What you want is :
count(preceding::product) +1
or, alternatively, the xsl:number
instruction can be used.
Here is a demonstration of both these methods :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:variable name="vLastProd" select=
"//product[@name='Back to the Future']"/>
<xsl:template match="/">
<xsl:value-of select="count($vLastProd/preceding::product) +1"/>
=========
<xsl:text/>
<xsl:apply-templates select="$vLastProd"/>
</xsl:template>
<xsl:template match="product">
<xsl:number level="any" count="product"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document :
<wishlists>
<wishlist name="Games">
<product name="Crash Bandicoot"/>
<product name="Super Mario Brothers"/>
<product name="Sonic the Hedgehog"/>
</wishlist>
<wishlist name="Movies">
<product name="Back to the Future"/>
</wishlist>
</wishlists>
the wanted, correct result is obtained using both methods -- and output :
4
=========
4
Note : The result of xsl:number
needs to be captured inside the body of a variable, if it will not be output directly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.