如何在XSLT中对XML节点的唯一组合值分组求和
XSLT实现XML节点唯一组合分组并求和
我来帮你搞定这个分组求和的需求!根据你提供的XML结构,我们需要按field1和field2的唯一组合对<row>节点分组,然后对每组的field3值求和。下面分两种常见的XSLT版本给出具体实现:
首先看你的XML示例(补全后)
<root> <row> <field1>720</field1> <field2>8900</field2> <field3>100</field3> </row> <row> <field1>720</field1> <field2>99998</field2> <field3>120</field3> </row> <row> <field1>720</field1> <field2>8900</field2> <field3>130</field3> </row> <row> <field1>720</field1> <field2>99998</field2> <field3>80</field3> </row> </root>
方案1:XSLT 2.0及以上(推荐,语法更简洁)
XSLT 2.0+支持原生的多键分组,用for-each-group指令就能轻松实现:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/root"> <root> <!-- 按field1和field2的组合分组 --> <xsl:for-each-group select="row" group-by="(field1, field2)"> <grouped-row> <field1><xsl:value-of select="current-group()/field1[1]"/></field1> <field2><xsl:value-of select="current-group()/field2[1]"/></field2> <!-- 对当前组的field3求和 --> <total-field3><xsl:value-of select="sum(current-group()/field3)"/></total-field3> </grouped-row> </xsl:for-each-group> </root> </xsl:template> </xsl:stylesheet>
代码解释:
group-by="(field1, field2)":直接指定两个字段作为分组键,XSLT会自动处理唯一组合current-group():指代当前分组内的所有<row>节点sum(current-group()/field3):计算当前组内所有field3值的总和
方案2:XSLT 1.0(兼容旧环境)
XSLT 1.0没有原生分组功能,需要用Muenchian分组法,通过定义键来实现:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 定义分组键:用field1和field2的拼接值作为唯一标识(用|分隔避免冲突) --> <xsl:key name="row-group" match="row" use="concat(field1, '|', field2)"/> <xsl:template match="/root"> <root> <!-- 遍历所有唯一分组的第一个节点 --> <xsl:for-each select="row[generate-id() = generate-id(key('row-group', concat(field1, '|', field2))[1])]"> <grouped-row> <field1><xsl:value-of select="field1"/></field1> <field2><xsl:value-of select="field2"/></field2> <!-- 对当前分组的field3求和 --> <total-field3><xsl:value-of select="sum(key('row-group', concat(field1, '|', field2))/field3)"/></total-field3> </grouped-row> </xsl:for-each> </root> </xsl:template> </xsl:stylesheet>
代码解释:
<xsl:key>:定义一个名为row-group的键,匹配<row>节点,键值是field1和field2拼接后的字符串(用|分隔是为了避免类似field1=12+field2=34和field1=1+field2=234这种拼接后相同的情况)row[generate-id() = generate-id(key('row-group', concat(field1, '|', field2))[1])]:只选择每个分组中的第一个节点,确保每个组合只处理一次key('row-group', ...):根据键值获取当前分组的所有节点,然后用sum()计算总和
最终输出示例
两种方案都会生成如下XML结果:
<root> <grouped-row> <field1>720</field1> <field2>8900</field2> <total-field3>230</total-field3> </grouped-row> <grouped-row> <field1>720</field1> <field2>99998</field2> <total-field3>200</total-field3> </grouped-row> </root>
内容的提问来源于stack exchange,提问作者Hsa
相关产品推荐
相关产品推荐

