Skip to Content

HCI: How to move a node in XML using XSLT mapping with condition

Hi!

I've got an xml similar to this:

<XML>
  <E1MARCM SEGMENT="1">
    <MSGFN>009</MSGFN>
    <WERKS>1010</WERKS>
  </E1MARCM>
  <E1MARCM SEGMENT="1">
    <MSGFN>005</MSGFN>
    <WERKS>1020</WERKS>
  </E1MARCM>
  <E1MBEWM SEGMENT="1">
    <BWKEY>1010</BWKEY>
    <ZPLPR>0</ZPLPR>
  </E1MBEWM>
  <E1MBEWM SEGMENT="1">
    <BWKEY>1020</BWKEY>
    <ZPLPR>1</ZPLPR>
  </E1MBEWM>
</XML> 

I need to move E1MBEWM nodes into appropriate E1MARCM node where BWKEY=WERKS

So, basically it should be the output like that:

<XML>
  <E1MARCM SEGMENT="1">
    <MSGFN>009</MSGFN>
    <WERKS>1010</WERKS>
      <E1MBEWM SEGMENT="1">
        <BWKEY>1010</BWKEY>
        <ZPLPR>0</ZPLPR>
      </E1MBEWM>
  </E1MARCM>
  <E1MARCM SEGMENT="1">
    <MSGFN>005</MSGFN>
    <WERKS>1020</WERKS>
      <E1MBEWM SEGMENT="1">
        <BWKEY>1020</BWKEY>
        <ZPLPR>1</ZPLPR>
      </E1MBEWM>
  </E1MARCM>
</XML> 

the possible issue is that sometimes E1MBEWM node might not be in incoming message.

I'm trying to use XSLT something like that:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:template match="node()|@*" name="identity">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>
 <xsl:template match="E1MARCM/*[1]">
  <xsl:copy-of select="/*/E1MBEWM[1]"/>
  <xsl:call-template name="identity"/>
 </xsl:template>
 <xsl:template match="/*/E1MBEWM[1]"/>
</xsl:stylesheet>

but it doesn't give result needed if there are several E1MARCM nodes. I understand that I need to use two for each cycles, but not sure how to implement it here.

Can you please help?


Add comment
10|10000 characters needed characters exceeded

  • Follow
  • Get RSS Feed

1 Answer

  • Sep 08, 2018 at 01:07 PM

    Hi Sergey

    Sorry that it took a while to get back to you :-) The following stylesheet creates the output you want:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    
        <xsl:template match="/">
            <XML>
                <xsl:apply-templates select="XML/E1MARCM"/>
            </XML>
        </xsl:template>
        
        <xsl:template match="E1MARCM">
            <xsl:copy>
                <xsl:apply-templates/>            
                <xsl:for-each select="/XML/E1MBEWM[BWKEY/text() = current()/WERKS/text()]">
                    <xsl:copy-of select="."/>
                </xsl:for-each>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="node() | @*">
            <xsl:copy>
                <xsl:apply-templates select="node() | @*"/>
            </xsl:copy>
        </xsl:template>
    
    </xsl:stylesheet>

    There's probably a more elegant solution, but until you find it, feel free to use this one :-)

    Regards,

    Morten

    Add comment
    10|10000 characters needed characters exceeded