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

XSLT按条件替换值问题:CUOBJ字段替换为BELNR值失败

问题描述

我需要将/SHPMNT05/IDOC/E1EDT20/E1EDL20/E1EDL37/E1EDL44/CUOBJ的内容替换为同层级E1EDL24下E1EDL43/BELNR的值,但当前XSL转换后CUOBJ字段仅返回true,无法得到预期结果。推测是ancestor::node()[3]部分的写法有误,求正确的XSL转换方案。

补充说明:E1EDL44元素数量可能多于E1EDL24,二者通过POSNR关联;E1EDL20的VBELN与E1EDL24的POSNR组合唯一,每个E1EDL24仅包含一个E1EDL43。

原始XML数据

<SHPMNT05>
    <IDOC BEGIN="1">
        <E1EDT20 SEGMENT="1">
            <TKNUM>0000287302</TKNUM>
            <E1EDL20 SEGMENT="1">
                <VBELN>0081018991</VBELN>
                <E1EDL24 SEGMENT="1">
                    <POSNR>000010</POSNR>
                    <MATNR>000000000000009645</MATNR>
                    <E1EDL43 SEGMENT="1">
                        <BELNR>0003196597</BELNR>
                    </E1EDL43>
                </E1EDL24>
                <E1EDL24 SEGMENT="1">
                    <POSNR>000020</POSNR>
                    <MATNR>000000000000009646</MATNR>
                    <E1EDL43 SEGMENT="1">
                        <BELNR>0003196598</BELNR>
                    </E1EDL43>
                </E1EDL24>
                <E1EDL37 SEGMENT="1">
                    <EXIDV>00387112831000247463</EXIDV>
                    <E1EDL44 SEGMENT="1">
                        <VBELN>0081018991</VBELN>
                        <POSNR>000010</POSNR>
                        <CUOBJ>000000000000000000</CUOBJ>
                    </E1EDL44>
                </E1EDL37>
                <E1EDL37 SEGMENT="1">
                    <EXIDV>00387112831000247470</EXIDV>
                    <E1EDL44 SEGMENT="1">
                        <VBELN>0081018991</VBELN>
                        <POSNR>000020</POSNR>
                        <VEMNG>5000.000</VEMNG>
                        <CUOBJ>000000000000000000</CUOBJ>
                    </E1EDL44>
                </E1EDL37>
            </E1EDL20>
        </E1EDT20>
    </IDOC>
</SHPMNT05>

当前使用的XSL代码

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all">

    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="node()|@*" mode="#all">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" mode="#current"/>
        </xsl:copy>
    </xsl:template>
    
    
    <xsl:template  match="/SHPMNT05/IDOC/E1EDT20/E1EDL20/E1EDL37/E1EDL44/CUOBJ">
      <CUOBJ> <xsl:value-of select="ancestor::node()[3]/VBELN=../VBELN and ancestor::node()[3]/E1EDL24/POSNR=../POSNR"/></CUOBJ>
        
       <xsl:for-each select="//E1EDL44">

      </xsl:for-each>
    
    
   </xsl:template>
        

</xsl:stylesheet>

当前转换结果

<SHPMNT05>
   <IDOC BEGIN="1">
      <E1EDT20 SEGMENT="1">
         <TKNUM>0000287302</TKNUM>
         <E1EDL20 SEGMENT="1">
            <VBELN>0081018991</VBELN>
            <E1EDL24 SEGMENT="1">
               <POSNR>000010</POSNR>
               <MATNR>000000000000009645</MATNR>
               <E1EDL43 SEGMENT="1">
                  <BELNR>0003196597</BELNR>
               </E1EDL43>
            </E1EDL24>
            <E1EDL24 SEGMENT="1">
               <POSNR>000020</POSNR>
               <MATNR>000000000000009646</MATNR>
               <E1EDL43 SEGMENT="1">
                  <BELNR>0003196597</BELNR>
               </E1EDL43>
            </E1EDL24>
            <E1EDL37 SEGMENT="1">
               <EXIDV>00387112831000247463</EXIDV>
               <E1EDL44 SEGMENT="1">
                  <VBELN>0081018991</VBELN>
                  <POSNR>000010</POSNR>
                  <CUOBJ>true</CUOBJ>
               </E1EDL44>
            </E1EDL37>
            <E1EDL37 SEGMENT="1">
               <EXIDV>00387112831000247470</EXIDV>
               <E1EDL44 SEGMENT="1">
                  <VBELN>0081018991</VBELN>
                  <POSNR>000020</POSNR>
                  <VEMNG>5000.000</VEMNG>
                  <CUOBJ>true</CUOBJ>
               </E1EDL44>
            </E1EDL37>
         </E1EDL20>
      </E1EDT20>
   </IDOC>
</SHPMNT05>

预期转换结果

<SHPMNT05>
   <IDOC BEGIN="1">
      <E1EDT20 SEGMENT="1">
         <TKNUM>0000287302</TKNUM>
         <E1EDL20 SEGMENT="1">
            <VBELN>0081018991</VBELN>
            <E1EDL24 SEGMENT="1">
               <POSNR>000010</POSNR>
               <MATNR>000000000000009645</MATNR>
               <E1EDL43 SEGMENT="1">
                  <BELNR>0003196597</BELNR>
               </E1EDL43>
            </E1EDL24>
            <E1EDL24 SEGMENT="1">
               <POSNR>000020</POSNR>
               <MATNR>000000000000009646</MATNR>
               <E1EDL43 SEGMENT="1">
                  <BELNR>0003196598</BELNR>
               </E1EDL43>
            </E1EDL24>
            <E1EDL37 SEGMENT="1">
               <EXIDV>00387112831000247463</EXIDV>
               <E1EDL44 SEGMENT="1">
                  <VBELN>0081018991</VBELN>
                  <POSNR>000010</POSNR>
                  <CUOBJ>0003196597</CUOBJ>
               </E1EDL44>
            </E1EDL37>
            <E1EDL37 SEGMENT="1">
               <EXIDV>00387112831000247470</EXIDV>
               <E1EDL44 SEGMENT="1">
                  <VBELN>0081018991</VBELN>
                  <POSNR>000020</POSNR>
                  <VEMNG>5000.000</VEMNG>
                  <CUOBJ>0003196598</CUOBJ>
               </E1EDL44>
            </E1EDL37>
         </E1EDL20>
      </E1EDT20>
   </IDOC>
</SHPMNT05>

解决方案

问题出在当前xsl:value-of返回的是布尔判断结果,而非对应的BELNR值。正确做法是先定位到同层级下匹配POSNR的E1EDL24节点,再取出其下的BELNR值。

修正后的XSL代码

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all">

    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <!-- 身份转换模板,保留所有原始内容 -->
    <xsl:template match="node()|@*" mode="#all">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" mode="#current"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- 处理CUOBJ节点,替换为匹配的BELNR值 -->
    <xsl:template match="/SHPMNT05/IDOC/E1EDT20/E1EDL20/E1EDL37/E1EDL44/CUOBJ">
        <xsl:variable name="current-posnr" select="../POSNR"/>
        <CUOBJ>
            <xsl:value-of select="ancestor::E1EDL20/E1EDL24[POSNR=$current-posnr]/E1EDL43/BELNR"/>
        </CUOBJ>
    </xsl:template>
</xsl:stylesheet>

说明

  1. 定义变量current-posnr,获取当前E1EDL44节点下的POSNR值作为关联条件;
  2. 通过ancestor::E1EDL20定位到共同父节点E1EDL20,筛选出其中POSNR与当前节点匹配的E1EDL24节点;
  3. 取出该E1EDL24节点下E1EDL43的BELNR值,替换CUOBJ内容;
  4. 移除原代码中无用的xsl:for-each循环,简化逻辑。

内容的提问来源于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.05 19:55:12