如何在XSLT 1.0中按Type统计唯一Code的数量?
解决XML中按Type统计唯一Code数量的问题
问题根源
你之前用concat(Type, Code)作为分组key,会把每个Type+Code的组合都当成独立分组,导致同一个Type被拆成多个组,最终输出重复的Type和错误计数。正确思路是先按Type分组,再在每个Type组内统计唯一Code的数量。
示例XML源数据
假设你的XML结构如下:
<Items> <Item> <Type>Can</Type> <Code>A1</Code> </Item> <Item> <Type>Can</Type> <Code>A2</Code> </Item> <Item> <Type>Can</Type> <Code>A1</Code> </Item> <Item> <Type>Can</Type> <Code>A3</Code> </Item> <Item> <Type>Tin</Type> <Code>B1</Code> </Item> <Item> <Type>Tin</Type> <Code>B2</Code> </Item> <Item> <Type>Tin</Type> <Code>B1</Code> </Item> </Items>
解决方案(XSLT 2.0+)
利用XSLT 2.0及以上的分组和去重功能,直接实现需求:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" /> <!-- 按Type分组所有Item --> <xsl:for-each-group select="/Items/Item" group-by="Type"> <!-- 提取当前Type组内的所有唯一Code --> <xsl:variable name="uniqueCodes" select="distinct-values(current-group()/Code)" /> <!-- 输出指定格式的结果 --> <xsl:value-of select="current-grouping-key(), ' - ', count($uniqueCodes)" /> <xsl:text> </xsl:text> <!-- 换行分隔结果 --> </xsl:for-each-group> </xsl:stylesheet>
解决方案(XSLT 1.0)
如果只能用XSLT 1.0,通过两次分组实现:先按Type+Code去重,再按Type统计数量:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" /> <!-- 定义key,用于按Type+Code去重 --> <xsl:key name="itemByTypeCode" match="Item" use="concat(Type, '|', Code)" /> <!-- 获取所有唯一的Type+Code组合 --> <xsl:variable name="uniqueTypeCodes" select="/Items/Item[generate-id() = generate-id(key('itemByTypeCode', concat(Type, '|', Code))[1])]" /> <!-- 按Type分组统计唯一Code数量 --> <xsl:for-each select="$uniqueTypeCodes"> <xsl:sort select="Type" /> <xsl:if test="generate-id() = generate-id(key('itemByTypeCode', concat(Type, '|', Code))[1]/../Item[Type=current()/Type][1])"> <xsl:value-of select="Type, ' - ', count(key('itemByTypeCode', concat(Type, '|', Code))/../Item[Type=current()/Type][generate-id() = generate-id(key('itemByTypeCode', concat(Type, '|', Code))[1])])" /> <xsl:text> </xsl:text> </xsl:if> </xsl:for-each> </xsl:stylesheet>
最终输出
两种方案都会得到符合预期的结果:
Can - 3 Tin - 2
内容的提问来源于stack exchange,提问作者Akash
相关产品推荐
相关产品推荐

