XSLT递归计算嵌套Item价格总和:最后一个Item未统计问题排查
问题分析与修复
你遇到的问题是递归计算时价格累加错误,最后一个item的价格没被正确计入,核心有两个错误:
错误1:当前item价格获取错误
在<xsl:for-each select="$items">循环内部,你用$items/price获取价格,这会取所有传入的items集合中的第一个price,而不是当前循环的item的price。比如处理第二个顶层item时,$items还是包含两个顶层item的集合,$items/price会取第一个item的10.00,而非当前item的2.00。
错误2:递归逻辑与输出时机错误
当前模板在递归到没有子item时就输出总和,导致每个分支都会单独输出一个total,而不是把所有item的价格汇总后输出。同时,递归调用的累加结果没有回传给上层,每个循环分支的累加都是独立的。
修复后的XSLT代码
我们可以用两种方式修复:
方式一:修正递归累加逻辑
让递归模板逐步累加所有item(包括子item)的价格,最后统一输出:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <total> <!-- 初始调用:传入所有顶层item,初始sum为0 --> <xsl:call-template name="sumPrices"> <xsl:with-param name="items" select="/order/item"/> <xsl:with-param name="sum" select="0"/> </xsl:call-template> </total> </xsl:template> <xsl:template name="sumPrices"> <xsl:param name="items"/> <xsl:param name="sum" select="0"/> <xsl:choose> <xsl:when test="$items"> <!-- 处理第一个item,累加它的价格 --> <xsl:variable name="currentSum" select="$sum + number($items[1]/price)"/> <!-- 先递归处理当前item的子item --> <xsl:variable name="childSum"> <xsl:call-template name="sumPrices"> <xsl:with-param name="items" select="$items[1]/item"/> <xsl:with-param name="sum" select="0"/> </xsl:call-template> </xsl:variable> <!-- 再递归处理剩余的同级item --> <xsl:call-template name="sumPrices"> <xsl:with-param name="items" select="$items[position() > 1]"/> <xsl:with-param name="sum" select="$currentSum + $childSum"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$sum"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
方式二:利用XPath内置函数简化
直接用sum()函数选择所有层级的item/price节点,无需手动递归:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <total> <xsl:value-of select="sum(//item/price)"/> </total> </xsl:template> </xsl:stylesheet>
验证结果
修复后计算的总和为10.00 + 5.00 + 2.00 + 2.00 = 19.00,完全符合预期。
内容的提问来源于stack exchange,提问作者code_scout
相关产品推荐
相关产品推荐

