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

如何在XSLT聚合求和中获取正确的总计值?

XSLT按report_id和type聚合求和并计算总计值

问题说明

作为XSLT新手,我已经被困数日,试图获取quantity的总计值。目前我能按report_id和type进行聚合求和,并舍弃负的聚合结果(如report_id 222和444),但总计值计算错误:

  • 当前输出:111 A=8; 111 B=4; 333 B=7; 0
  • 期望输出:111 A=8; 111 B=4; 333 B=7; 19

XML数据源

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <report>
        <report_id>111</report_id>
        <group>
            <type>A</type>
            <quantity>2</quantity>
        </group>
        <group>
            <type>B</type>
            <quantity>4</quantity>
        </group>
        <group>
            <type>A</type>
            <quantity>6</quantity>
        </group>
    </report>
    <report>
        <report_id>222</report_id>
        <group>
            <type>A</type>
            <quantity>-5</quantity>
        </group>
        <group>
            <type>A</type>
            <quantity>2</quantity>
        </group>
    </report>
    <report>
        <report_id>333</report_id>
        <group>
            <type>B</type>
            <quantity>7</quantity>
        </group>
    </report>
    
    <report>
        <report_id>444</report_id>
        <group>
            <type>B</type>
            <quantity>-12</quantity>
        </group>
    </report>
</root>

我的XSLT代码(存在问题)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet exclude-result-prefixes="xsl"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
    <xsl:output method="text" />
    <xsl:template match="/root">
        <xsl:variable name="total_qty" select="0"/>
        <xsl:variable name="grand_qty" select="0"/>
        <xsl:for-each-group select="report/group" group-by="concat(../report_id, '|', type)">
            <xsl:variable name="qty" select="sum(current-group()/quantity)"/>
            <xsl:if test="$qty &gt; 0">
                <xsl:variable name="total_qty" select="$qty + $total_qty"/>
                <xsl:value-of select="concat(../report_id, ' ', type, '=', $total_qty, '; ')"/>
                <xsl:variable name="grand_qty" select="$grand_qty + $total_qty"/>
            </xsl:if>
        </xsl:for-each-group>
        <xsl:value-of select="$grand_qty"/>
    </xsl:template>
</xsl:stylesheet>

问题原因

XSLT中的变量是不可变的——一旦定义就无法修改。你在for-each-group内部重新定义的$total_qty和$grand_qty是局部变量,和外层同名变量完全无关,所以外层的$grand_qty始终保持初始值0。

修正后的XSLT代码(XSLT 2.0兼容)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet exclude-result-prefixes="xsl"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="text" />
    <xsl:template match="/root">
        <!-- 先计算所有有效分组的结果,存储为节点集 -->
        <xsl:variable name="valid-groups">
            <xsl:for-each-group select="report/group" group-by="concat(../report_id, '|', type)">
                <xsl:variable name="qty" select="sum(current-group()/quantity)"/>
                <xsl:if test="$qty > 0">
                    <group-entry>
                        <report-id><xsl:value-of select="../report_id"/></report-id>
                        <type><xsl:value-of select="type"/></type>
                        <sum><xsl:value-of select="$qty"/></sum>
                    </group-entry>
                </xsl:if>
            </xsl:for-each-group>
        </xsl:variable>
        
        <!-- 遍历有效分组输出 -->
        <xsl:for-each select="$valid-groups/group-entry">
            <xsl:value-of select="concat(report-id, ' ', type, '=', sum, '; ')"/>
        </xsl:for-each>
        
        <!-- 计算并输出总计值 -->
        <xsl:value-of select="sum($valid-groups/group-entry/sum)"/>
    </xsl:template>
</xsl:stylesheet>

代码解释

  1. 先通过for-each-group计算所有符合条件(求和结果>0)的分组,将每个分组的report_id、type和求和结果存储到临时节点集$valid-groups中。
  2. 遍历临时节点集输出每个分组的信息。
  3. 使用sum()函数直接对临时节点集中的所有sum节点求和,得到总计值。

内容的提问来源于stack exchange,提问作者Pete

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:35:22