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

如何在XSLT中对每行key匹配计算的数值递归求和并生成汇总行

实现方案

直接在现有代码基础上新增递归求和模板,在所有数据行渲染完成后新增汇总行即可,修改后的完整XSLT代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    xmlns:date="http://exslt.org/dates-and-times"
    extension-element-prefixes="date"
    >
    
    <!--unique key-->
    <xsl:key name="aux" match="Item[Code='auxiliary']" use="concat(CodeIdentifier, '|', generate-id(..))"/>
    
    <xsl:decimal-format name="generalFormat" grouping-separator="," decimal-separator="." /> 
    <xsl:output method="xml" indent="yes" />

    <!-- 新增:分组数量求和递归模板 -->
    <xsl:template name="sumGroupsQty">
      <xsl:param name="groups" select="/.."/>
      <xsl:param name="sum" select="0"/>
      <xsl:choose>
        <xsl:when test="$groups">
          <xsl:variable name="currentGroup" select="$groups[1]"/>
          <xsl:variable name="currentVal" select="$currentGroup/DispatchQuantity/@quantity * count(key('aux', concat($currentGroup/CodeIdentifier, '|', generate-id($currentGroup/..))))"/>
          <xsl:call-template name="sumGroupsQty">
            <xsl:with-param name="groups" select="$groups[position() > 1]"/>
            <xsl:with-param name="sum" select="$sum + $currentVal"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$sum"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

    <!-- 新增:分组重量求和递归模板 -->
    <xsl:template name="sumGroupsWeight">
      <xsl:param name="groups" select="/.."/>
      <xsl:param name="sum" select="0"/>
      <xsl:choose>
        <xsl:when test="$groups">
          <xsl:variable name="currentGroup" select="$groups[1]"/>
          <xsl:variable name="currentVal" select="$currentGroup/DispatchQuantity/@quantity * count(key('aux', concat($currentGroup/CodeIdentifier, '|', generate-id($currentGroup/..)))) * $currentGroup/Dimension[@type='unitNetWeight']/@quantity"/>
          <xsl:call-template name="sumGroupsWeight">
            <xsl:with-param name="groups" select="$groups[position() > 1]"/>
            <xsl:with-param name="sum" select="$sum + $currentVal"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$sum"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
    
    <xsl:template match="/" name="Barcode">
        
        <fo:root>
            <fo:layout-master-set>
                <fo:simple-page-master master-name="ManufacturLabelSize-first" page-height="297mm" page-width="210mm"  margin-top="25.4mm" margin-right="25.4mm" margin-left="25.4mm" margin-bottom="25.4mm">
                    <fo:region-body margin-top="15mm" />
                    <fo:region-before />
                    <fo:region-after />
                </fo:simple-page-master>
            </fo:layout-master-set>
            
            <fo:page-sequence master-reference="ManufacturLabelSize-first" id="pSeqID">
                
                <fo:flow flow-name="xsl-region-body">
                    
                    <fo:table>
                        
                        <fo:table-body border="solid" border-width="0.5pt">
                            <xsl:for-each select="cXML/Header/Line">
                                <xsl:for-each select="Items">
                                <fo:table-row>
                                    <fo:table-cell>
                                        <!--DispatchQuantity*occurence-->
                                        <fo:block>
                                            <xsl:for-each select="Item[Code='auxiliary'][count(. | key('aux', concat(CodeIdentifier, '|', generate-id(..)))[1]) = 1]">
                                                <fo:block >
                                                    <xsl:value-of select="(DispatchQuantity/@quantity) * count(key('aux', concat(CodeIdentifier, '|', generate-id(..))))"/>
                                                </fo:block>
                                            </xsl:for-each>
                                        </fo:block>
                                    </fo:table-cell>
                                    
                                    <fo:table-cell>
                                        <!--unique code-->
                                        <fo:block>
                                            <xsl:for-each select="Item[Code='auxiliary'][count(. | key('aux', concat(CodeIdentifier, '|', generate-id(..)))[1]) = 1]"> 
                                                <fo:block >
                                                    <xsl:value-of select="CodeIdentifier"/>
                                                </fo:block>
                                            </xsl:for-each>
                                        </fo:block>
                                    </fo:table-cell>
                                    
                                    <fo:table-cell>
                                        <!--(DispatchQuantity*occurence)*UnitNetWeight-->
                                        <fo:block>
                                            <xsl:for-each select="Item[Code='auxiliary'][count(. | key('aux', concat(CodeIdentifier, '|', generate-id(..)))[1]) = 1]">
                                                 <fo:block font-size="8" font-family="Calibri" padding-before="2mm" start-indent="0.75mm">
                                                    <xsl:value-of select="(DispatchQuantity/@quantity) * count(key('aux', concat(CodeIdentifier, '|', generate-id(..)))) * Dimension[@type='unitNetWeight']/@quantity"/>
                                                </fo:block>
                                                
                                            </xsl:for-each>
                                        </fo:block>
                                    </fo:table-cell>
                                </fo:table-row>
                            </xsl:for-each>
                            </xsl:for-each>

                            <!-- 新增:汇总行开始 -->
                            <xsl:variable name="allAuxGroups" select="//Item[Code='auxiliary'][count(. | key('aux', concat(CodeIdentifier, '|', generate-id(..)))[1]) = 1]"/>
                            <fo:table-row font-weight="bold">
                                <fo:table-cell padding-before="2mm" border-top="solid 0.5pt black">
                                    <fo:block>
                                        <xsl:call-template name="sumGroupsQty">
                                            <xsl:with-param name="groups" select="$allAuxGroups"/>
                                        </xsl:call-template>
                                    </fo:block>
                                </fo:table-cell>
                                <fo:table-cell padding-before="2mm" border-top="solid 0.5pt black">
                                    <fo:block>合计</fo:block>
                                </fo:table-cell>
                                <fo:table-cell padding-before="2mm" border-top="solid 0.5pt black">
                                    <fo:block>
                                        <xsl:call-template name="sumGroupsWeight">
                                            <xsl:with-param name="groups" select="$allAuxGroups"/>
                                        </xsl:call-template>
                                    </fo:block>
                                </fo:table-cell>
                            </fo:table-row>
                            <!-- 新增:汇总行结束 -->
                            
                        </fo:table-body>          
                    </fo:table> 
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
        
    </xsl:template>
    
</xsl:stylesheet>

效果说明

渲染后会在所有数据行的最后新增一行加粗的汇总行,第一列显示总数量16,第二列显示「合计」,第三列显示总重量48,和需求完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 22:54:04