Sorted exsl:node-set. Return node by it position
I have a set of nodes
<menuList>
<mode name="aasdf"/>
<mode name="vfssdd"/>
<mode name="aswer"/>
<mode name="ddffe"/>
<mode name="ffrthjhj"/>
<mode name="dfdf"/>
<mode name="vbdg"/>
<mode name="wewer"/>
<mode name="mkiiu"/>
<mode name="yhtyh"/>
and so on...
</menuList>
I have it sorted now this way
<xsl:variable name="rtf">
&l开发者_如何学Got;xsl:for-each select="//menuList/mode">
<xsl:sort data-type="text" order="ascending" select="@name"/>
<xsl:value-of select="@name"/>
</xsl:for-each>
</xsl:variable>
Now I need to get an arbitrary element in the sorted array to the number of its position. I'm using the code:
<xsl:value-of select="exsl:node-set($rtf)[position() = 3]"/>
and I get a response error. How should I be doing it?
There are at least two errors in the provided code:
<xsl:value-of select="@name"/>
When more than one adjacent text node exist, they are combined into one. The result is that the RTF has just one (long) single text node, and there isn't a 3rd node.
2
.<xsl:value-of select="exsl:node-set($rtf)[position() = 3]"/>
This asks for the third node contained in exsl:node-set($rtf)
, however exsl:node-set($rtf)
is the document node of the temporary tree produced by the exsl:node-set()
extension function -- this is only one node. Therefore the above XPath expression doesn't select anything at all.
One correct solution is the following:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
>
<xsl:template match="/">
<xsl:variable name="rtf">
<xsl:for-each select="//menuList/mode">
<xsl:sort data-type="text" order="ascending" select="@name"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="msxsl:node-set($rtf)/*[position()=3]/@name"/>
</xsl:template>
</xsl:stylesheet>
You use <xsl:value-of>
in your variable. This does not copy the node, but its string value (the node's @name
attribute value). This means you produce a variable containing a concatenated string, but nothing with a structure.
Try:
<xsl:variable name="rtf">
<xsl:for-each select="//menuList/mode">
<xsl:sort select="@name" data-type="text" order="ascending" />
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
Now your variable contains a result tree fragment consisting of <mode>
nodes in your preferred order, which means that this:
<xsl:value-of select="exsl:node-set($rtf)/*[3]/@name" />
<!-- don't forget you have element nodes now! ^^^^^^ -->
would work. Also note that …/*[position() = 3]
and …/*[3]
are the same thing.
精彩评论