如何用XSLT统计lastname/age组合的去重数量?
问题:统计XML中lastname与age组合的去重总数
这是Stack Overflow问题《Grouping & counting by two XML elements with XSLT》的跟进问题。
输入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>
现有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>
当前输出
Name Age # brown 25 1 smith 40 2 smith 75 1 Total distinct (lastname only): 2
需求
需要统计lastname与age组合的去重总数(即上述表格的行数3),而非仅统计去重的lastname数量。
解决方案
你已经通过<xsl:key name="cust" match="cust" use="concat(lastname, age)"/>实现了按lastname+age组合分组,直接复用这个分组逻辑即可统计去重组合的数量:
修改现有XSLT中统计总数的行,将原来统计lastname去重数量的代码替换为统计分组后节点的数量:
Total distinct (lastname+age): <xsl:value-of select="count(cust[count(. | key('cust', concat(lastname, age))[1]) = 1])"/>
修改后的完整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+age): <xsl:value-of select="count(cust[count(. | key('cust', concat(lastname, age))[1]) = 1])"/> </body> </html> </xsl:template>
最终输出
Name Age # brown 25 1 smith 40 2 smith 75 1 Total distinct (lastname+age): 3
原理说明
表达式cust[count(. | key('cust', concat(lastname, age))[1]) = 1]会筛选出每个(lastname, age)组合的第一个节点,统计这些节点的数量,就是去重后的组合总数,和表格的行数完全一致。
内容的提问来源于stack exchange,提问作者mgr326639
相关产品推荐
相关产品推荐

