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

如何编写适配两种XML结构的XSLT 2.0转换脚本?

需求说明

需要用XSLT 2.0转换两种结构不同的XML输入,得到统一的指定输出。现有基于for-each-group的脚本能正常处理第一种XML,但处理第二种时会出现MATNR重复的错误。

第一种XML结构

<DELIVERY>
<E1EDP07>
    <E1EDP08>
        <EXIDV>SSCC_CODE_C1</EXIDV>
        <PCKAR>CARTON</PCKAR>
    </E1EDP08>
    <E1EDP08>
        <EXIDV>SSCC_CODE_P1</EXIDV>
        <PCKAR>WP</PCKAR>
    </E1EDP08>
    <E1EDP09>
    <MATNR>PRODUCT_A</MATNR>
    </E1EDP09>
</E1EDP07>

<E1EDP07>
    <E1EDP08>
        <EXIDV>SSCC_CODE_C1</EXIDV>
        <PCKAR>CARTON</PCKAR>
    </E1EDP08>
    <E1EDP08>
        <EXIDV>SSCC_CODE_P1</EXIDV>
        <PCKAR>WP</PCKAR>
    </E1EDP08>
    <E1EDP09>
    <MATNR>PRODUCT_B</MATNR>
    </E1EDP09>
</E1EDP07>

<E1EDP07>
    <E1EDP08>
        <EXIDV>SSCC_CODE_C2</EXIDV>
        <PCKAR>CARTON</PCKAR>
    </E1EDP08>
    <E1EDP08>
        <EXIDV>SSCC_CODE_P2</EXIDV>
        <PCKAR>WP</PCKAR>
    </E1EDP08>
    <E1EDP09>
    <MATNR>PRODUCT_C</MATNR>
    </E1EDP09>
</E1EDP07>
</DELIVERY>

第二种XML结构

<DELIVERY>
<E1EDP07>
    <E1EDP08>
        <EXIDV>SSCC_CODE_C1</EXIDV>
        <PCKAR>CARTON</PCKAR>
    </E1EDP08>
    <E1EDP08>
        <EXIDV>SSCC_CODE_P1</EXIDV>
        <PCKAR>WP</PCKAR>
    </E1EDP08>
    <E1EDP08>   
        <EXIDV>SSCC_CODE_C1</EXIDV>
        <PCKAR>CARTON</PCKAR>
    </E1EDP08>
    <E1EDP08>
        <EXIDV>SSCC_CODE_P1</EXIDV>
        <PCKAR>WP</PCKAR>
    </E1EDP08>
    <E1EDP08>   
        <EXIDV>SSCC_CODE_C2</EXIDV>
        <PCKAR>CARTON</PCKAR>
    </E1EDP08>
    <E1EDP08>
        <EXIDV>SSCC_CODE_P2</EXIDV>
        <PCKAR>WP</PCKAR>
    </E1EDP08>

    <E1EDP09>
        <MATNR>PRODUCT_A</MATNR>
    </E1EDP09>
    <E1EDP09>
        <MATNR>PRODUCT_B</MATNR>
    </E1EDP09>
    <E1EDP09>
        <MATNR>PRODUCT_C</MATNR>
    </E1EDP09>
</E1EDP07>
</DELIVERY>

期望输出

<EXIDV>SSCC_CODE_C1</EXIDV>
    <MATNR>PRODUCT_A</MATNR>
    <MATNR>PRODUCT_B</MATNR>

<EXIDV>SSCC_CODE_C2</EXIDV>
    <MATNR>PRODUCT_C</MATNR>

当前使用的XSLT 2.0脚本

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <DELIVERY>
            <xsl:for-each-group select="DELIVERY/E1EDP07/E1EDP08[PCKAR='CARTON']" group-by="EXIDV" >

            <EXIDV>
                <xsl:value-of select="EXIDV"/>
            </EXIDV>

            <xsl:for-each select="current-group()">
                <MATNR>
                    <xsl:value-of select="../E1EDP09/MATNR"/>
                </MATNR>
            </xsl:for-each>

        </xsl:for-each-group>
            
    </DELIVERY>
</xsl:template>
</xsl:stylesheet>

问题分析

原脚本的问题在于:

  • 第一种XML中,每个<E1EDP07>下只有一个<E1EDP09>,../E1EDP09/MATNR只会取到一个值;
  • 第二种XML中,单个<E1EDP07>下有多个<E1EDP09>,且对应多个<E1EDP08>(CARTON类型),此时../E1EDP09/MATNR会返回所有MATNR值,加上遍历current-group()时重复处理同组条目,导致MATNR重复输出。

修改后的XSLT脚本

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <DELIVERY>
            <!-- 按EXIDV分组所有CARTON类型的E1EDP08 -->
            <xsl:for-each-group select="DELIVERY/E1EDP07/E1EDP08[PCKAR='CARTON']" group-by="EXIDV">
                <EXIDV>
                    <xsl:value-of select="EXIDV"/>
                </EXIDV>
                <!-- 获取当前组所有条目对应的MATNR并去重 -->
                <xsl:for-each select="distinct-values(current-group()/../E1EDP09/MATNR)">
                    <MATNR>
                        <xsl:value-of select="."/>
                    </MATNR>
                </xsl:for-each>
            </xsl:for-each-group>
        </DELIVERY>
    </xsl:template>
</xsl:stylesheet>

脚本说明

  1. 保留原有的按EXIDV分组逻辑,确保同一SSCC_CODE的CARTON被归为一组;
  2. 用distinct-values(current-group()/../E1EDP09/MATNR)替换原遍历逻辑:
    • current-group()/../E1EDP09/MATNR获取当前组内所有CARTON条目所属<E1EDP07>下的所有MATNR值;
    • distinct-values()函数自动去重,避免重复输出相同的MATNR;
  3. 该逻辑适配两种XML结构,无论每个<E1EDP07>下对应单个还是多个MATNR,都能输出唯一的MATNR列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:15:35