简体   繁体   中英

XSL to replace value by condition

I want to replace the contents of /SHPMNT05/IDOC/E1EDT20/E1EDL20/E1EDL37/E1EDL44/CUOBJ with the value of /SHPMNT05/IDOC/E1EDT20/E1EDL20/E1EDL24/E1EDL43/BELNR but the best I can get is a 'true' with my xsl transformation:(

My 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>

My 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>

Current result:

<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>

Required result:

<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>

Link: https://xsltfiddle.liberty-development.net/aUPRNr

I'm afraid I made a mess with the ancestor::node()[3] part... Each time I think I'learning something / know how 'to fix it' the challenge becomes too big:(

Update: forgot to mention. there can be more E1EDL44 than E1EDL24 elements. SAP Idoc always starts with E1EDL24 'lines' which shows the lines in a delivery. Then you get E1EDL37 Handling units below with 1 or more E1EDL44 lines on that handling unit. The relation between 24 and 44 is on POSNR. Also there can be multiple E1EDL20 elements (deliveries) each with eg an E1EDL24 with POSNR 10. So the combination E1EDL20\VBELN E1EDL24\POSNR is unique. There is only one E1EDL43 in E1EDL24.

Kind regards,

Mike

-- edited in view of clarifications --

So, now that we know that there exists a cross-reference between E1EDL24 and E1EDL44 in the form of a common value of POSNR , we can use a key to implement a link between the two.

And, since the value of POSNR is unique only within the E1EDT20 branch, we need to include the unique id of the branch in the key:

XSLT 1.0

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

<xsl:key name="e1edl24" match="E1EDL24" use="concat(POSNR, '|', generate-id(ancestor::E1EDT20))" />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="CUOBJ">
    <xsl:copy>
        <xsl:value-of select="key('e1edl24', concat(../POSNR, '|', generate-id(ancestor::E1EDT20)))/E1EDL43/BELNR"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM