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

XSLT转换后出现重复E1EDT20元素的排查与修正请求

提问:转换结果出现两个E1EDT20元素,求排查原因

我希望有人能告诉我,为什么我的转换结果中会出现两个E1EDT20元素?肯定是重复复制了,但我找不到问题所在。

我的输入XML

<SHPMNT05>
   <IDOC BEGIN="1">
      <EDI_DC40 SEGMENT="1">
         <TABNAM>EDI_DC40</TABNAM>
      </EDI_DC40>
      <E1EDT20 SEGMENT="1">
         <TKNUM>0000287214</TKNUM>
         <E1EDL20 SEGMENT="1">
            <VBELN>0081018702</VBELN>
            <ABLAD>1</ABLAD>
            <VSTEL>EWM</VSTEL>
            <VKORG>0100</VKORG>
         </E1EDL20>
         <E1EDL20 SEGMENT="1">
            <VBELN>0081018703</VBELN>
            <ABLAD>1</ABLAD>
            <VSTEL>EWM</VSTEL>
            <VKORG>0210</VKORG>
         </E1EDL20>
      </E1EDT20>
   </IDOC>
</SHPMNT05>

我的XSL

<?xml version="1.0" encoding="UTF-8"?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
   
     <xsl:template match="E1EDT20">
       
       
       <xsl:copy>
      
    <xsl:copy-of select="*[not(self::E1EDL20)]"/>
       
      <xsl:copy>
         <xsl:for-each-group select="E1EDL20" group-adjacent="concat(ABLAD, '|', VKORG)" >
            <CMR>
              <xsl:copy-of select="current-group()"/>
            </CMR>
         </xsl:for-each-group>
      </xsl:copy>
      </xsl:copy>
      
   </xsl:template>
</xsl:stylesheet>

当前转换结果

<SHPMNT05>
   <IDOC BEGIN="1">
      <EDI_DC40 SEGMENT="1">
         <TABNAM>EDI_DC40</TABNAM>
      </EDI_DC40>
      <E1EDT20>
         <TKNUM>0000287214</TKNUM>
         <E1EDT20>
            <CMR>
               <E1EDL20 SEGMENT="1">
                  <VBELN>0081018702</VBELN>
                  <ABLAD>1</ABLAD>
                  <VSTEL>EWM</VSTEL>
                  <VKORG>0100</VKORG>
               </E1EDL20>
            </CMR>
            <CMR>
               <E1EDL20 SEGMENT="1">
                  <VBELN>0081018703</VBELN>
                  <ABLAD>1</ABLAD>
                  <VSTEL>EWM</VSTEL>
                  <VKORG>0210</VKORG>
               </E1EDL20>
            </CMR>
         </E1EDT20>
      </E1EDT20>
   </IDOC>
</SHPMNT05>

期望结果

<SHPMNT05>
    <IDOC BEGIN="1">
        <EDI_DC40 SEGMENT="1">
            <TABNAM>EDI_DC40</TABNAM>
        </EDI_DC40>
        <E1EDT20>
            <TKNUM>0000287214</TKNUM>
            <CMR>
                <E1EDL20 SEGMENT="1">
                    <VBELN>0081018702</VBELN>
                    <ABLAD>1</ABLAD>
                    <VSTEL>EWM</VSTEL>
                    <VKORG>0100</VKORG>
                </E1EDL20>
            </CMR>
            <CMR>
                <E1EDL20 SEGMENT="1">
                    <VBELN>0081018703</VBELN>
                    <ABLAD>1</ABLAD>
                    <VSTEL>EWM</VSTEL>
                    <VKORG>0210</VKORG>
                </E1EDL20>
            </CMR>
        </E1EDT20>
    </IDOC>
</SHPMNT05>

我已经接近目标了(感谢社区支持 :)),肯定是犯了低级错误..


回答

问题出在你处理E1EDT20的模板里,多写了一层不必要的<xsl:copy>标签。

你的模板外层已经通过<xsl:copy>复制了当前的E1EDT20节点,但内部又嵌套了一个<xsl:copy>,这会再次生成一个E1EDT20节点,最终导致结果里出现嵌套的两个E1EDT20。

只需要把内部那个多余的<xsl:copy>和对应的闭合标签删掉,直接将分组逻辑放在外层的<xsl:copy>内部即可。

修改后的XSL代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
   
    <xsl:template match="E1EDT20">
        <xsl:copy>
            <xsl:copy-of select="*[not(self::E1EDL20)]"/>
            <!-- 移除多余的<xsl:copy>标签 -->
            <xsl:for-each-group select="E1EDL20" group-adjacent="concat(ABLAD, '|', VKORG)">
                <CMR>
                    <xsl:copy-of select="current-group()"/>
                </CMR>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

执行修改后的XSL转换,就能得到你期望的结果,不会再出现嵌套的E1EDT20元素。

内容的提问来源于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.08 01:45:35