XSLT按层级条件对行项目求和计算总毛重的实现咨询
解决方案
完全可以通过XSLT实现该需求,以下是兼容XSLT 1.0的通用实现方案,不需要依赖任何扩展函数,可直接在所有支持XSLT 1.0的环境运行,运行后针对你给出的示例XML输出的总毛重为预期的122。
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fo="http://www.w3.org/1999/XSL/Format" > <xsl:output method="xml" indent="yes"/> <!-- 总入口模板 --> <xsl:template match="Main" > <root> <TotalGrossWeight> <xsl:call-template name="calculateTotal"> <xsl:with-param name="items" select="Item"/> </xsl:call-template> </TotalGrossWeight> </root> </xsl:template> <!-- 递归计算所有Item总和的模板 --> <xsl:template name="calculateTotal"> <xsl:param name="items" /> <xsl:param name="sumSoFar" select="0" /> <xsl:choose> <xsl:when test="not($items)"> <xsl:value-of select="$sumSoFar" /> </xsl:when> <xsl:otherwise> <!-- 取第一个Item计算它的总和 --> <xsl:variable name="currentItem" select="$items[1]" /> <xsl:variable name="isMultiLevel" select="count($currentItem/Line[Level=2]) > 0" /> <xsl:variable name="itemSum"> <xsl:call-template name="calculateItemSum"> <xsl:with-param name="lines" select="$currentItem/Line" /> <xsl:with-param name="isMultiLevel" select="$isMultiLevel" /> </xsl:call-template> </xsl:variable> <!-- 递归处理剩余Item --> <xsl:call-template name="calculateTotal"> <xsl:with-param name="items" select="$items[position() > 1]" /> <xsl:with-param name="sumSoFar" select="$sumSoFar + $itemSum" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- 计算单个Item内所有行总和的模板 --> <xsl:template name="calculateItemSum"> <xsl:param name="lines" /> <xsl:param name="isMultiLevel" /> <xsl:param name="itemSumSoFar" select="0" /> <xsl:choose> <xsl:when test="not($lines)"> <xsl:value-of select="$itemSumSoFar" /> </xsl:when> <xsl:otherwise> <xsl:variable name="currentLine" select="$lines[1]" /> <xsl:variable name="lineValue"> <xsl:choose> <xsl:when test="$isMultiLevel"> <xsl:value-of select="$currentLine/Weight" /> </xsl:when> <xsl:otherwise> <xsl:value-of select="$currentLine/Weight + $currentLine/Count" /> </xsl:otherwise> </xsl:choose> </xsl:variable> <!-- 递归处理剩余行 --> <xsl:call-template name="calculateItemSum"> <xsl:with-param name="lines" select="$lines[position() > 1]" /> <xsl:with-param name="isMultiLevel" select="$isMultiLevel" /> <xsl:with-param name="itemSumSoFar" select="$itemSumSoFar + $lineValue" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
核心逻辑说明
- 第一层递归遍历所有
<Item>节点,逐个计算每个Item的总和 - 处理每个Item前先判断是否存在
Level=2的行,确定该Item的计算规则 - 第二层递归遍历单个Item下的所有
<Line>节点,按照确定的规则计算每行的值并累加 - 所有Item计算完成后输出总毛重
内容的提问来源于stack exchange,提问作者Akash
相关产品推荐
相关产品推荐

