You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 01:05:05