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

XSLT中for-each循环内变量求和失效问题求助

解决XSLT for-each循环里求和始终为0的问题

为啥你的代码会失效?

问题出在XSLT的变量特性上——XSLT里的变量一旦定义就不能被修改!你在for-each内部写的<xsl:variable name="sum" select="$sum + $result" />,并不是更新外层那个初始值为0的$sum,而是每次循环都创建了一个新的局部$sum变量,这个变量只在当前循环迭代里有效,外层的$sum从头到尾都是0,所以最后输出肯定是0啦。

两种靠谱的解决办法

根据你用的XSLT版本,选对应的方法就行:

方法1:XSLT 1.0 用递归模板求和

如果你的环境只能支持XSLT 1.0,那就用递归模板来实现累加逻辑:

<xsl:template match="/">
    <xsl:call-template name="calculate-total-weight">
        <xsl:with-param name="item-list" select="Details/Package/Items"/>
        <xsl:with-param name="running-total" select="0"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="calculate-total-weight">
    <xsl:param name="item-list"/>
    <xsl:param name="running-total" select="0"/>
    
    <xsl:choose>
        <!-- 还有未处理的商品,继续递归 -->
        <xsl:when test="$item-list">
            <!-- 解析当前商品的重量,把逗号换成小数点转成数字 -->
            <xsl:variable name="current-weight" select="number(concat(substring-before($item-list[1]/IWeight, ','), '.', substring-after($item-list[1]/IWeight, ',')))"/>
            
            <!-- 递归处理剩下的商品,把当前重量加到累计值里 -->
            <xsl:call-template name="calculate-total-weight">
                <xsl:with-param name="item-list" select="$item-list[position() > 1]"/>
                <xsl:with-param name="running-total" select="$running-total + $current-weight"/>
            </xsl:call-template>
        </xsl:when>
        <!-- 所有商品处理完了,输出总和 -->
        <xsl:otherwise>
            <xsl:value-of select="$running-total"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

方法2:XSLT 2.0+ 直接用sum函数一步搞定

如果你的环境支持XSLT 2.0或更高版本,那就简单太多了!不用写循环,直接用sum()函数配合XPath表达式就能算出总和:

<!-- 一行代码搞定转换+求和 -->
<xsl:variable name="total-weight" select="sum(Details/Package/Items/(number(concat(substring-before(IWeight, ','), '.', substring-after(IWeight, ',')))))"/>
<xsl:value-of select="$total-weight"/>

要是觉得一行代码太挤,拆成两步更清晰:

<!-- 先把所有重量转换成标准数字格式 -->
<xsl:variable name="converted-weights" select="Details/Package/Items/(number(concat(substring-before(IWeight, ','), '.', substring-after(IWeight, ','))))"/>
<!-- 再求和 -->
<xsl:variable name="total-weight" select="sum($converted-weights)"/>
<xsl:value-of select="$total-weight"/>

测试结果

用你提供的XML示例测试,两种方法都会输出3.5(对应1,000转成1.0,2,500转成2.5,加起来就是3.5),和XML里的TotalWeight值一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 23:07:44