XSLT 1.0实现Shipment层级下修正后Product LineValue求和
XSLT 1.0 Shipment层级商品实际总价值求和方案
方法1:纯XSLT 1.0递归求和模板
这是XSLT 1.0中处理动态节点集求和的标准方案,无需依赖任何扩展函数,兼容性拉满。
实现思路
- 定义递归模板,接收待处理的
Product节点列表、当前累加总和两个参数 - 每次处理列表首节点,计算其实际价值并累加到总和中
- 递归处理剩余节点,直到节点列表为空时返回最终总和
完整代码示例
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 主入口:匹配Shipment节点触发求和 --> <xsl:template match="/Shipment"> <xsl:call-template name="sumActualProductValues"> <xsl:with-param name="productNodes" select=".//Product"/> <xsl:with-param name="currentTotal" select="0"/> </xsl:call-template> </xsl:template> <!-- 递归求和核心模板 --> <xsl:template name="sumActualProductValues"> <xsl:param name="productNodes"/> <xsl:param name="currentTotal"/> <xsl:choose> <!-- 仍有未处理的Product节点 --> <xsl:when test="$productNodes"> <!-- 计算当前节点的实际价值 --> <xsl:variable name="singleValue" select="($productNodes[1]/LineValue div $productNodes[1]/OrderedQty) * $productNodes[1]/DeliveredQty"/> <!-- 递归处理剩余节点,累加当前值 --> <xsl:call-template name="sumActualProductValues"> <xsl:with-param name="productNodes" select="$productNodes[position() > 1]"/> <xsl:with-param name="currentTotal" select="$currentTotal + $singleValue"/> </xsl:call-template> </xsl:when> <!-- 所有节点处理完成,输出最终总和 --> <xsl:otherwise> <xsl:value-of select="$currentTotal"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
关键提示
- 若源数据存在
OrderedQty=0的异常情况,需在计算单个价值前增加判断:<xsl:if test="$productNodes[1]/OrderedQty != 0">,避免除零错误 .//Product会匹配Shipment下所有层级的Product节点,若你的XML结构有特定路径,可替换为更精确的节点选择器(比如Package/Product)
方法2:扩展函数求和(需处理器支持)
如果你的XSLT处理器支持exsl:node-set扩展(如Xalan、Saxon),可以用更简洁的方式实现:先生成所有实际价值的临时节点集,再用sum()直接求和。
完整代码示例
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl"> <xsl:output method="text" encoding="UTF-8"/> <xsl:template match="/Shipment"> <!-- 生成包含所有实际价值的临时节点 --> <xsl:variable name="actualValueNodes"> <xsl:for-each select=".//Product"> <value> <xsl:value-of select="(LineValue div OrderedQty) * DeliveredQty"/> </value> </xsl:for-each> </xsl:variable> <!-- 转换临时节点为可查询集合并求和 --> <xsl:value-of select="sum(exsl:node-set($actualValueNodes)/value)"/> </xsl:template> </xsl:stylesheet>
注意事项
- 该方案代码更简洁,但依赖处理器对EXSLT扩展的支持,兼容性不如纯递归方案
- 同样需要处理
OrderedQty=0的异常场景
内容的提问来源于stack exchange,提问作者Vp Soini
相关产品推荐
相关产品推荐

