XSLT-3中统计重复description额外出现次数并添加至输出首行
统计XML中重复description的额外出现次数并生成指定输出
我来给你梳理下怎么实现这个需求——要在输出报告的首行,统计所有出现次数超过一次的description元素的额外出现总数(也就是每个重复项的「出现次数-1」相加的结果),同时保留所有条目输出,还要在首行说明具体的重复项和贡献值。
实现思路
- 分组统计次数:用XSLT的
<xsl:key>对所有description元素按文本内容分组,统计每个内容的出现次数。 - 计算额外次数总和:遍历所有分组,对出现次数大于1的分组,累加「次数-1」得到总额外次数。
- 生成首行说明:把总次数和对应的重复项说明拼接成首行文本。
- 输出所有条目:按原XML的顺序输出所有包含
description的条目内容。
完整XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 按description文本内容分组(处理空格统一) --> <xsl:key name="desc-key" match="description" use="normalize-space(.)"/> <!-- 计算额外出现次数的表达式(用于首行说明) --> <xsl:variable name="extra-expression"> <xsl:for-each select="description[generate-id() = generate-id(key('desc-key', normalize-space(.))[1])]"> <xsl:variable name="count" select="count(key('desc-key', normalize-space(.)))"/> <xsl:if test="$count > 1"> <xsl:value-of select="$count - 1"/> <xsl:if test="position() != last()">+</xsl:if> </xsl:if> </xsl:for-each> </xsl:variable> <!-- 生成重复项的说明文本 --> <xsl:variable name="summary-text"> <xsl:for-each select="description[generate-id() = generate-id(key('desc-key', normalize-space(.))[1])]"> <xsl:variable name="count" select="count(key('desc-key', normalize-space(.)))"/> <xsl:if test="$count > 1"> <xsl:text>"</xsl:text> <xsl:value-of select="normalize-space(.)"/> <xsl:text>" was found </xsl:text> <xsl:value-of select="$count"/> <xsl:text> times</xsl:text> <xsl:if test="position() != last()">, and </xsl:if> </xsl:if> </xsl:for-each> </xsl:variable> <xsl:template match="/"> <!-- 输出首行:总额外次数 + 说明 --> <xsl:value-of select="sum(//description[generate-id() = generate-id(key('desc-key', normalize-space(.))[1])][count(key('desc-key', normalize-space(.))) > 1]/(count(key('desc-key', normalize-space(.))) - 1))"/> <xsl:text> (because </xsl:text> <xsl:value-of select="$summary-text"/> <xsl:text>, thus </xsl:text> <xsl:value-of select="$extra-expression"/> <xsl:text> )</xsl:text> <xsl:text> </xsl:text> <!-- 按原顺序输出所有条目 --> <xsl:for-each select="//*[description]"> <xsl:value-of select="normalize-space(preceding-sibling::*[1])"/> <xsl:text> </xsl:text> <xsl:value-of select="normalize-space(description)"/> <xsl:text> </xsl:text> <xsl:value-of select="normalize-space(following-sibling::*[1])"/> <xsl:text> </xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet>
关键部分解释
<xsl:key>分组:通过normalize-space(.)统一处理文本的空格问题,避免因空格差异导致相同内容被误判为不同分组。- 总额外次数计算:用
sum()函数直接累加所有重复项的「次数-1」,同时用$extra-expression变量保存用于说明的计算式(比如1+2)。 - 首行说明拼接:遍历每个唯一的重复
description,拼接出对应的次数说明文本,让首行的解释更清晰。 - 条目输出:遍历所有包含
description的节点,按原XML顺序输出相邻的编号、描述、数值内容,保证输出结构和原数据一致。
这样处理后,就能完全匹配你期望的输出格式啦~
内容的提问来源于stack exchange,提问作者Jeka Tay
相关产品推荐
相关产品推荐

