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

XSL按Byordnum和Num分组计算小计问题求助

XML分组小计问题解决方案

问题描述

需要基于Byordnum和Num两个字段对XML中的<Line>元素分组,计算Delqua字段的小计,但当前XSL代码未生效,输出与输入完全一致。

输入XML

<DeliHomeBasic_DesAdv>
    <InboundDlvNumber/>
    <ExternalDlvNumber>WSP0059837_SCU0000001_1</ExternalDlvNumber>
    <DeliveryDate>2023-01-16</DeliveryDate>
    <SupplierName>Weekamp Doors SRO</SupplierName>
    <Cpss>
        <Cps>
            <Line>1</Line>
            <Subline>0</Subline>
            <Pacs>
                <Pac>
                    <Qua>1</Qua>
                </Pac>
            </Pacs>
        </Cps>
        <Cps>
            <Line>2</Line>
            <Subline>1</Subline>
            <Pacs>
                <Pac>
                    <Qua>1</Qua>
                    <Iso>2</Iso>
                    <Sscc>WPA0135955</Sscc>
                    <Sscc2>80689</Sscc2>
                </Pac>
            </Pacs>
            <Lines>
                <Line>
                    <Num>00960</Num>
                    <Byart>WK_RA_UITZET</Byart>
                    <Desc>Top hang window, 895x1370x54 FSCHW</Desc>
                    <Delqua>1</Delqua>
                    <Byordnum>4500428486</Byordnum>
                </Line>
                <Line>
                    <Num>00960</Num>
                    <Byart>WK_RA_UITZET</Byart>
                    <Desc>Top hang window, 895x1370x54 FSCHW</Desc>
                    <Delqua>1</Delqua>
                    <Byordnum>4500428486</Byordnum>
                </Line>
                <Line>
                    <Num>00960</Num>
                    <Byart>WK_RA_UITZET</Byart>
                    <Desc>Top hang window, 895x1370x54 FSCHW</Desc>
                    <Delqua>1</Delqua>
                    <Byordnum>4500428486</Byordnum>
                </Line>
                <Line>
                    <Num>00970</Num>
                    <Byart>WK_RA_UITZET</Byart>
                    <Desc>Top hang window, 895x1495x54 FSCHW</Desc>
                    <Delqua>1</Delqua>
                    <Byordnum>4500428486</Byordnum>
                </Line>
                <Line>
                    <Num>00970</Num>
                    <Byart>WK_RA_UITZET</Byart>
                    <Desc>Top hang window, 895x1495x54 FSCHW</Desc>
                    <Delqua>1</Delqua>
                    <Byordnum>4500428486</Byordnum>
                </Line>
                <Line>
                    <Num>00990</Num>
                    <Gtin/>
                    <Byart>WK_TB_DEUR</Byart>
                    <Desc>WK046, 830x2120x38 FSC® cert. Premium Hardwood</Desc>
                    <Delqua>1</Delqua>
                    <Byordnum>4500428486</Byordnum>
                    <Suordnum>SOR0061481</Suordnum>
                </Line>
            </Lines>
        </Cps>
    </Cpss>
</DeliHomeBasic_DesAdv>

现有XSL代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    
      <xsl:key name="k1" match="/Line" use="concat(Byordnum, '|', Num, '|', generate-id(..))"/>
    
      <!-- identity transform -->
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
    
     <xsl:template match="/Lines">
        <xsl:copy>
          <xsl:for-each select="/Lines[generate-id()=generate-id(key('k1', concat(Byordnum,'|',Num, '|', generate-id(..)))[1])]">
            <xsl:copy>
              <xsl:copy-of select="Num"/>
              <xsl:copy-of select="Gtin"/>
              <xsl:copy-of select="Byart"/>
              <Delqua>
                <xsl:value-of select="sum(key('k1', concat(Byordnum,'|',Num, '|', generate-id(..)))/Delqua)" />
              </Delqua>
              <xsl:copy-of select="Byordnum"/>
              <xsl:copy-of select="Suordnum"/>
            </xsl:copy>
          </xsl:for-each>
        </xsl:copy>
      </xsl:template>
    </xsl:stylesheet>

期望输出

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DeliHomeBasic_DesAdv>
    <InboundDlvNumber/>
    <ExternalDlvNumber>WSP0059837_SCU0000001_1</ExternalDlvNumber>
    <DeliveryDate>2023-01-16</DeliveryDate>
    <SupplierName>Weekamp Doors SRO</SupplierName>
    <Cpss>
        <Cps>
            <Line>1</Line>
            <Subline>0</Subline>
            <Pacs>
                <Pac>
                    <Qua>1</Qua>
                </Pac>
            </Pacs>
        </Cps>
        <Cps>
            <Line>2</Line>
            <Subline>1</Subline>
            <Pacs>
                <Pac>
                    <Qua>1</Qua>
                    <Iso>2</Iso>
                    <Sscc>WPA0135955</Sscc>
                    <Sscc2>80689</Sscc2>
                </Pac>
            </Pacs>
            <Lines>
                <Line>
                    <Num>00960</Num>
                    <Byart>WK_RA_UITZET</Byart>
                    <Desc>Top hang window, 895x1370x54 FSCHW</Desc>
                    <Delqua>3</Delqua>
                    <Byordnum>4500428486</Byordnum>
                </Line>
                <Line>
                    <Num>00970</Num>
                    <Byart>WK_RA_UITZET</Byart>
                    <Desc>Top hang window, 895x1495x54 FSCHW</Desc>
                    <Delqua>2</Delqua>
                    <Byordnum>4500428486</Byordnum>
                </Line>
                <Line>
                    <Num>00990</Num>
                    <Gtin/>
                    <Byart>WK_TB_DEUR</Byart>
                    <Desc>WK046, 830x2120x38 FSC® cert. Premium Hardwood</Desc>
                    <Delqua>1</Delqua>
                    <Byordnum>4500428486</Byordnum>
                    <Suordnum>SOR0061481</Suordnum>
                </Line>
            </Lines>
        </Cps>
    </Cpss>
</DeliHomeBasic_DesAdv>

问题原因及修正方案

问题分析

  1. 节点匹配路径错误:
    • xsl:key中match="/Line"试图匹配根节点下的<Line>,但实际<Line>嵌套在<Lines>内部,应改为相对路径match="Line"。
    • 模板match="/Lines"同样错误,根节点下无直接的<Lines>,需改为match="Lines"以匹配所有嵌套的<Lines>节点。
  2. 分组逻辑错误:
    • xsl:for-each选择的是<Lines>节点而非<Line>节点,无法实现按<Line>分组。
    • 分组键多余加入了父节点IDgenerate-id(..),导致相同Byordnum+Num的<Line>被错误拆分。
  3. 节点遗漏:原代码未复制<Desc>节点,无法匹配期望输出中的该字段。

修正后的XSL代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    
    <!-- 按Byordnum和Num的组合作为分组键 -->
    <xsl:key name="k1" match="Line" use="concat(Byordnum, '|', Num)"/>
    
    <!-- 身份转换模板:复制未被特殊处理的节点 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- 处理Lines节点,生成分组后的Line元素 -->
    <xsl:template match="Lines">
        <xsl:copy>
            <!-- 选择每个分组中的第一个Line节点,作为分组代表 -->
            <xsl:for-each select="Line[generate-id() = generate-id(key('k1', concat(Byordnum, '|', Num))[1])]">
                <xsl:copy>
                    <!-- 复制Line下除Delqua外的所有必要子节点 -->
                    <xsl:copy-of select="Num|Gtin|Byart|Desc|Byordnum|Suordnum"/>
                    <!-- 计算当前分组的Delqua总和 -->
                    <Delqua>
                        <xsl:value-of select="sum(key('k1', concat(Byordnum, '|', Num))/Delqua)"/>
                    </Delqua>
                </xsl:copy>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

修正说明

  • 简化分组键:仅使用Byordnum和Num的组合,确保相同属性的<Line>被归为一组。
  • 修正匹配路径:确保能正确定位到所有<Line>和<Lines>节点。
  • 补全节点复制:加入<Desc>节点的复制,符合期望输出要求。
  • 正确分组选择:通过generate-id()筛选每个分组的第一个<Line>,实现分组去重并计算小计。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:25:25