XSLT按ItemLevel=3分组计算重量及总汇总问题求助
问题根源
你当前的代码问题出在两个核心逻辑上:
- 没有对所有
ItemLevel=3的条目按ItemType做正确分组:你现在是遍历<Item>节点,同一个<Item>下如果有多个不同ItemType的ItemLevel=3条目,只会取到第一个,导致Clock、Pen这类条目丢失 - 重量求和逻辑错误:总重量计算时的节点取值路径有误,导致累加结果不符合预期
修正方案
XSLT 1.0下用Muenchian分组法实现按ItemType分组,调整重量计算逻辑即可,完整代码如下:
<?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:decimal-format name="generalFormat" grouping-separator="," decimal-separator="." /> <!-- 新增按ItemType分组的key,核心用于Muenchian分组 --> <xsl:key name="itemTypeGroup" match="Items[ItemLevel='3']" use="ItemType"/> <xsl:template match="/" name="Barcode"> <fo:root> <fo:layout-master-set> <fo:simple-page-master master-name="ManufacturLabelSize-first" page-height="100mm" page-width="100mm"> <fo:region-body margin-top="15mm" /> <fo:region-before /> <fo:region-after /> </fo:simple-page-master> <fo:simple-page-master master-name="ManufacturLabelSize-rest" page-height="100mm" page-width="100mm"> <fo:region-body margin-top="15mm"/> <fo:region-before /> <fo:region-after /> </fo:simple-page-master> <fo:page-sequence-master master-name="ManufacturLabelSize-portrait"> <fo:repeatable-page-master-alternatives> <fo:conditional-page-master-reference master-reference="ManufacturLabelSize-first" page-position="first"/> <fo:conditional-page-master-reference master-reference="ManufacturLabelSize-rest" page-position="rest"/> </fo:repeatable-page-master-alternatives> </fo:page-sequence-master> </fo:layout-master-set> <fo:page-sequence master-reference="ManufacturLabelSize-portrait" id="pSeqID"> <fo:flow flow-name="xsl-region-body"> <fo:table> <fo:table-body> <fo:table-row> <fo:table-cell><fo:block>Descp:</fo:block></fo:table-cell> <fo:table-cell> <fo:block>Weight:</fo:block></fo:table-cell> </fo:table-row> <fo:table-row> <fo:table-cell> <fo:block> <xsl:call-template name="line"></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:template name="line"> <fo:table> <fo:table-body> <xsl:apply-templates select="cXML/Request/Header"/> </fo:table-body> </fo:table> </xsl:template> <xsl:template match="Header" name="pallet"> <!-- 遍历每个ItemType分组的首个节点,实现按描述分组 --> <xsl:for-each select="//Items[ItemLevel='3'][count(. | key('itemTypeGroup', ItemType)[1]) = 1]"> <fo:table-row> <fo:table-cell> <fo:block><xsl:value-of select="ItemType"/></fo:block> </fo:table-cell> <fo:table-cell start-indent="25mm"> <!-- 取当前分组首个条目的单位重量 --> <xsl:variable name="unitNetWeight" select="Dimension[@type='unitNetWeight']/@quantity"/> <!-- 求当前分组所有条目的发货量总和 --> <xsl:variable name="totalQty" select="sum(key('itemTypeGroup', ItemType)/DispatchQuantity/@quantity)"/> <fo:block><xsl:value-of select="$unitNetWeight * $totalQty"/></fo:block> </fo:table-cell> </fo:table-row> </xsl:for-each> <fo:table-row> <fo:table-cell start-indent="10mm"> <fo:block>Total</fo:block> </fo:table-cell> <fo:table-cell start-indent="25mm"> <!-- 递归计算总重量 --> <xsl:variable name="Total"> <xsl:call-template name="calcTotalWeight"> <xsl:with-param name="groups" select="//Items[ItemLevel='3'][count(. | key('itemTypeGroup', ItemType)[1]) = 1]"/> </xsl:call-template> </xsl:variable> <fo:block><xsl:value-of select="$Total"/></fo:block> </fo:table-cell> </fo:table-row> </xsl:template> <!-- 总重量计算模板 --> <xsl:template name="calcTotalWeight"> <xsl:param name="groups"/> <xsl:param name="sum" select="0"/> <xsl:choose> <xsl:when test="$groups"> <xsl:variable name="currentGroupFirst" select="$groups[1]"/> <xsl:variable name="groupWeight" select="$currentGroupFirst/Dimension[@type='unitNetWeight']/@quantity * sum(key('itemTypeGroup', $currentGroupFirst/ItemType)/DispatchQuantity/@quantity)"/> <xsl:call-template name="calcTotalWeight"> <xsl:with-param name="groups" select="$groups[position()>1]"/> <xsl:with-param name="sum" select="$sum + $groupWeight"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$sum"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
核心修改说明
- 新增分组key实现按
ItemType归类所有ItemLevel=3的条目,解决漏项问题 - 替换原有的双层
<Level>/<Item>遍历逻辑,改为遍历每个分组的首个节点,保证每个品类单独输出一行 - 修正单品类重量计算逻辑:取分组首个条目的单位重量,乘以同组所有发货量的总和
- 重写总重量计算逻辑,直接累加所有品类的重量结果,避免节点路径取值错误
内容的提问来源于stack exchange,提问作者Akash
相关产品推荐
相关产品推荐

