This is a follow up question to Grouping & counting by two XML elements with XSLT
This is my input XML:
<root>
<cust>
<firstname>bob</firstname>
<lastname>smith</lastname>
<age>40</age>
</cust>
<cust>
<firstname>joe</firstname>
<lastname>smith</lastname>
<age>75</age>
</cust>
<cust>
<firstname>joe</firstname>
<lastname>brown</lastname>
<age>25</age>
</cust>
<cust>
<firstname>pete</firstname>
<lastname>smith</lastname>
<age>40</age>
</cust>
</root>
After processing it with this XSLT:
<xsl:key name="cust" match="cust" use="concat(lastname, age)"/>
<xsl:key name="dist_cnt" match="/root/cust/lastname/text()" use="."/>
<xsl:template match="/root">
<html>
<body>
<table border="1">
<tr>
<th>Name</th>
<th>Age</th>
<th>#</th>
</tr>
<xsl:for-each select="cust[count(. | key('cust', concat(lastname, age))[1]) = 1]">
<xsl:sort select="lastname"/>
<tr>
<td>
<xsl:value-of select="lastname"/>
</td>
<td>
<xsl:value-of select="age"/>
</td>
<td>
<xsl:value-of select="count(key('cust', concat(lastname, age)))"/>
</td>
</tr>
</xsl:for-each>
</table>
Total distinct (lastname only): <xsl:value-of select="count(/root/cust/lastname/text()[generate-id() = generate-id(key('dist_cnt',.)[1])])"/>
</body>
</html>
</xsl:template>
The result is as follows
Name Age #
brown 25 1
smith 40 2
smith 75 1
Total distinct (lastname only): 2
What I’m really interested in is the number 3, the number of rows of the output table.
The result "Total distinct (lastname only): 2" is just my first attempt at reaching that goal. It shows that I have managed to count the distinct number of lastname’s. But I didn’t get any further than that.
I’d like the result to be the total number of distinct lastname/age combinations.
>Solution :
It can be much simpler than you’re making it:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="cust" match="cust" use="concat(lastname, age)"/>
<xsl:template match="/root">
<xsl:variable name="distinct-customers" select="cust[count(. | key('cust', concat(lastname, age))[1]) = 1]" />
<html>
<body>
<table border="1">
<tr>
<th>Name</th>
<th>Age</th>
<th>#</th>
</tr>
<xsl:for-each select="$distinct-customers">
<xsl:sort select="lastname"/>
<tr>
<td>
<xsl:value-of select="lastname"/>
</td>
<td>
<xsl:value-of select="age"/>
</td>
<td>
<xsl:value-of select="count(key('cust', concat(lastname, age)))"/>
</td>
</tr>
</xsl:for-each>
</table>
<xsl:text>Total distinct: </xsl:text>
<xsl:value-of select="count($distinct-customers)"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>