Reputation: 11
Currently, I have many "xsl:choose" conditions in my file - one "xsl:choose" for a single letter, and it works well. I try to simplify this situation by replacing many "xsl:choose" with 'for-each' loop - however with no luck.
It's seems to me, that count() inside 'for-each' always returns 0. I'm curious, because the same count() without 'for-each' works OK.
Pls help.
<?xml version="1.0"?>
<stocks>
<names date="10/30/2013" time="20:37:12">
<name>WGOS1</name>
<name>WGOS2</name>
<name>WGOS3</name>
<name>WGOS4</name>
<name>WGOS5</name>
</names>
<loc>
<slot>P</slot>
<slot>P</slot>
<slot>P</slot>
<slot>P</slot>
<slot>H</slot>
<slot>S</slot>
</loc>
<loc>
<slot>P</slot>
<slot>P</slot>
<slot>P</slot>
<slot>S</slot>
When I use 'count' function to count values eg. 'B' in 'loc' node, it's works OK
<xsl:variable name="color-table">
<var code="A">pink</var >
<var code="B">silver</var>
<var code="P">red</var>
<var code="D">pink</var>
<var code="H">yellow</var>
<var code="S">lightblue</var>
<var code="T">green</var>
<var code="W">pink</var>
</xsl:variable>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="count(/stocks/loc[$pos]/slot [. eq 'B']) > 0">
<td class="slot-B">
<xsl:value-of select="count(/stocks/loc[$pos]/slot [. eq 'B'])"/>
<xsl:text>B</xsl:text>
</td>
</xsl:when>
</xsl:choose>
But when I try to do the same inside for-each loop - test condition fails, due the count() result is always 0.
<xsl:for-each select="$color-table/var">
<xsl:variable name="p" select="@code"/>
<xsl:choose>
<xsl:when test="count(/stocks/loc[$pos]/slot [. eq $p]) > 0">
<td class="slot-$p">
<xsl:value-of select="count(/stocks/loc[$pos]/slot [. eq $p])"/>
<xsl:value-of select="$p"/>
</td>
</xsl:when>
</xsl:choose>
</xsl:for-each>
Upvotes: 1
Views: 425
Reputation: 122414
The $color-table
variable refers to a temporary tree, so when you're inside a
<xsl:for-each select="$color-table/var">
/
is the root of that temporary tree, not the root of the original document, and thus /stocks/loc[$pos]/slot
will not find any nodes.
You need to store the outer /
in another variable before you go into the for-each
.
<xsl:variable name="slash" select="/" />
<xsl:for-each select="$color-table/var">
<xsl:variable name="p" select="@code"/>
<xsl:choose>
<xsl:when test="count($slash/stocks/loc[$pos]/slot [. eq $p]) > 0">
<td class="slot-{$p}">
<xsl:value-of select="count($slash/stocks/loc[$pos]/slot [. eq $p])"/>
<xsl:value-of select="$p"/>
</td>
</xsl:when>
</xsl:choose>
</xsl:for-each>
But rather than iterating over the color-table, it may be more efficient to just for-each-group
over the slots themselves
<xsl:for-each-group select="/stocks/loc[$pos]/slot" group-by=".">
<td class="slot-{current-grouping-key()}">
<xsl:value-of select="count(current-group())" />
<xsl:value-of select="current-grouping-key()" />
</td>
</xsl:for-each-group>
Upvotes: 1