如何在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
相关产品推荐
相关产品推荐

