Conditional position-check in XSLT
I have an XSLT file which renders articles. I'm passing a variable into the XSLT file which is supposed to limit the number of records output. The trouble is, this 'limit' variable is optional - if it's not there the XSLT file needs to output all values; if the 'limit' variable is a number, then it needs to only output that 开发者_开发技巧number of items (presumably using a position() test).
Here's my code:
<xsl:variable name="limit" select="/macro/limit"/>
<xsl:template match="/">
<xsl:variable name="allNodes" select="$localSiteRoot/descendant-or-self::*[articles != '']"/>
<xsl:for-each select="$allNodes">
<div class="articleItem">
<h3><xsl:value-of select="./articleHeader"/></h3>
<xsl:if test="./articleSubheader != ''">
<h4><xsl:value-of select="./articleSubheader"/></h4>
</xsl:if>
</div>
</xsl:for-each>
</xsl:template>
Clearly I could just do an XSLT choose around this and say
<xsl:choose>
<xsl:when select="$limit!= ''">
<xsl:if test="position() < $limit">
But then I'd need to repeat the code twice. There must be a better way, perhaps using templates, but I just can't figure out how it would work and my XSLT isn't great.
Could anyone point me in the right direction with the best/neatest way to approach this?
Thanks!
Just use:
<xsl:for-each select="$allNodes[not(position() > $limit)]">
Explanation:
If the value of
$limit
is castable to a number, then the expression in theselect
attribute above selects not more than$limit
nodes.If the value of
$limits
isn't castable to a number (e.g. empty or 'abc') then it is converted to NaN. By definition comparisons involving NaN are alwaysfalse()
, therefore the predicatenot(position() > $limit
istrue()
and in this case all nodes in$allNodes
are selected.
精彩评论