I have a very similar problem to this: Need XSLT transform to remove duplicate elements - sorted by an attribute. I took the solution from the best answer and slightly modified it. I have to count the statuses, but taking into account only the latest results.
My template looks like this:
<xsl:template match='Results/Result' mode='countstatus'>
<xsl:param name='status' select='"Pass"'/>
<xsl:for-each select="key('sn-key', SerialNumber)">
<xsl:sort select='./Date' order='descending'/>
<xsl:if test='((position() = 1) and (./Status=$status))'>
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:template>
I don't want to display all the matched results but only the number of items returned after this template is applied.
My key definition is <xsl:key name='sn-key' match='Results/Result' use='SerialNumber'/>
and I call this template with <xsl:apply-templates select='Results/Result[generate-id() = generate-id(key("sn-key", SerialNumber)[1])]' mode='countstatus'/>
.
EDIT
With fresh mind I see that my question is a bit unclear. Here are more details.
My input looks like this:
<Results>
<Result ID="0">
<SerialNumber>3333</SerialNumber>
<Status>Fail</Status>
<Date>21</Date>
</Result>
<Result ID="1">
<SerialNumber>1111</SerialNumber>
<Status>Fail</Status>
<Date>34</Date>
</Result>
<Result ID="2">
<SerialNumber>1111</SerialNumber>
<Status>Pass</Status>
<Date>67</Date>
</Result>
<Result ID="3">
<SerialNumber>2222</SerialNumber>
<Status>Fail</Status>
<Date>40</Date>
</Result>
<Result ID="4">
<SerialNumber>1111</SerialNumber>
<Status>Fail</Status>
<Date>55</Date>
</Result>
<Result ID="5">
<SerialNumber>1111</SerialNumber>
<Status>Fail</Status>
<Date>88</Date>
</Result>
<Result ID="6">
<SerialNumber>2222</SerialNumber>
<Status>Fail</Status>
<Date>22</Date>
</Result>
<Result ID="7">
<SerialNumber>1111</SerialNumber>
<Status>Fail</Status>
<Date>86</Date>
</Result>
<Result ID="8">
<SerialNumber>3333</SerialNumber>
<Status>Pass</Status>
<Date>99</Date>
</Result>
</Results>
I would like to count e.g. how many times the Fail
status occurs, but considering only the latest results for SerialNumber
. The template I showed earlier displays all the latest results for SerialNumber
(but for status Pass
). I would like to display just the number. In example when looking for the number of fails I would like to display 2
instead of [1111 Fail 88, 2222 Fail 40]
.
My transformation look like this now (but I need something else):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name='sn-key' match='Results/Result' use='SerialNumber' />
<xsl:template match="/">
<xsl:apply-templates select="Results/Result[generate-id()=generate-id(key('sn-key', SerialNumber)[1])]"/>
</xsl:template>
<xsl:template match="Results/Result">
<xsl:param name='status' select='"Fail"'/>
<xsl:for-each select="key('sn-key', SerialNumber)">
<xsl:sort select="./Date" order="descending"/>
<xsl:if test='((position() = 1) and (./Status=$status))'>
<xsl:value-of select="."/><br />
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>