0

I have an xml with repeating BPART segment and need to create repeating segment in output xml. To construct the xml I am using variables in a for loop. There are two elements(Doc_Number & Q_Number) which need to be picked from other repeatable segment BCOAD. If it has 2 BPART segments then from the 1st occurrence of BCOAD pick Doc_Number & Q_Number and put in 1st output segment of BPART and from the 2nd occurrence of BCOAD pick Doc_Number & Q_Number and put in 2nd output segment of BPART. so need to extract 2 variables:-

<xsl:variable name="Doc_Number"
<xsl:variable name="Q_Number"
.

Output variable should be like:-

1st occurrence:-

<Doc_Number>0000023378</Doc_Number>
<Q_Number>001</Q_Number>

2nd occurrence:-

<Doc_Number>9164412232</Doc_Number>
<Q_Number>002</Q_Number>

Part of output XML:-

<Row>
    <Doc_Number>0000023378</Doc_Number>
    <Q_Number>001</Q_Number>
    <PartNumber>JK</PartNumber>
    <ADDRESS>0000027647</ADDRESS>
</Row>
<Row>
    <Doc_Number>9164412232</Doc_Number>
    <Q_Number>002</Q_Number>
    <PartNumber>UU</PartNumber>
    <ADDRESS>9164412232</ADDRESS>
</Row>

Input XML:-

    <?xml version="1.0" encoding="UTF-8"?>
<ORDERS>
    <IDOC BEGIN="1">
        <MESTYP>ORDERS</MESTYP>
        <E1EDKA1 SEGMENT="1">
            <PARVW>KL</PARVW>
            <PARTN>WXA</PARTN>
            <TELF1>6788899</TELF1>
            <BNAME>RTTTYY</BNAME>
            <PAORG>WXA</PAORG>
            <ORGTX>FGHYUIUI</ORGTX>
            <PAGRU>002</PAGRU>
            <ILNNR>45666</ILNNR>
        </E1EDKA1>
        <Z1E1P SEGMENT="1">
            <ORDER>5467899</ORDER>
            <ACCOUNT>X</ACCOUNT>
            <Z1BP_ISAORDER SEGMENT="1">
                <DPART SEGMENT="1">
                    <PARVW>DF</PARVW>
                    <PARTN_ROLE>JK</PARTN_ROLE>
                    <CONTACT>0000000000</CONTACT>
                    <ORT01>AGHY</ORT01>
                    <LAND1>US</LAND1>
                    <TELF1>6789990</TELF1>
                    <ADDRESS>0000027647</ADDRESS>
                </DPART>
                <DPART SEGMENT="1">
                    <PARVW>DF</PARVW>
                    <ORT01>TYYUI</ORT01>
                    <LAND1>US</LAND1>
                    <TELF1>66777889</TELF1>
                    <PARTN_ROLE>UU</PARTN_ROLE>
                    <CONTACT>0000000000</CONTACT>
                    <ADDRESS>9164412232</ADDRESS>
                </DPART>            
                <BPART SEGMENT="1">
                    <PARTN_ROLE>JK</PARTN_ROLE>
                    <CONTACT>0000000000</CONTACT>
                    <ADDRESS>0000027647</ADDRESS>
                </BPART>
                <BPART SEGMENT="1">
                    <PARTN_ROLE>UU</PARTN_ROLE>
                    <CONTACT>0000000000</CONTACT>
                    <ADDRESS>9164412232</ADDRESS>
                </BPART>
                <E1EDS01 SEGMENT="1">
                    <SUMID>002</SUMID>
                    <SUMME>18.52</SUMME>
                    <GETDETAILEDLI SEGMENT="1">
                        <BCOAD SEGMENT="1">
                            <Doc_Number>0000023378</Doc_Number>
                            <NAME>John</NAME>
                            <STREET>gyhu</STREET>
                            <Q_Number>001</Q_Number>
                        </BCOAD>
                        <BCOAD SEGMENT="1">
                            <Doc_Number>9164412232</Doc_Number>
                            <NAME>Michael</NAME>
                            <STREET>ABCH</STREET>
                            <Q_Number>002</Q_Number>
                        </BCOAD>
                    </GETDETAILEDLI>
                </E1EDS01>
            </Z1BP_ISAORDER>    
        </Z1E1P>
    </IDOC>
</ORDERS>

It needs to be handled using XSLT 1.0 I tried below XSLT but not getting the output, xslt:-

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <!--Delivery number -->
    <!-- <xsl:variable name="deliveryNumber" select="node()/DataArea/Dispatch/DispatchHead/DispatchId/Id"/>  -->
    <xsl:variable name="MessageType" select="node()/IDOC/MESTYP"/>
    
    <xsl:variable name="SenderID">
    <xsl:if test="exists(node()/IDOC/E1EDKA1[PARVW='KL']/ILNNR)">
        <xsl:copy-of select="node()/IDOC/E1EDKA1[PARVW='KL']/ILNNR">
        </xsl:copy-of>
    </xsl:if>
    </xsl:variable>
    <!-- Template to copy the nodes as they are -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/">
<Order>
            <Envelope>
                <Version>1.8</Version>
                <MessageType>
                    <xsl:value-of select="$MessageType"/>
                </MessageType>
                <SenderID>
                    <xsl:value-of select="$SenderID"/>
                </SenderID>
            </Envelope>
            <Head>
                <Addresses>
                    <xsl:for-each select="node()/IDOC/Z1E1P/Z1BP_ISAORDER/DPART">
                    <!-- PARVW = WE -->
                    <xsl:if test="./PARVW='DF'  ">
                        <Address>
                            <City>
                                <xsl:value-of select="./ORT01"/>
                            </City>
                            <CountryCode>
                                <xsl:value-of select="./LAND1"/>
                            </CountryCode>
                            <MobilePhoneNumber>
                                <xsl:value-of select="./TELF1"/>
                            </MobilePhoneNumber>
                        </Address>
                    </xsl:if>
                    </xsl:for-each>
                </Addresses>
            </Head>
            <Rows>
            <xsl:for-each select="node()/IDOC/Z1E1P/Z1BP_ISAORDER/BPART">
                    <!-- PARVW = WE or AG or LF or ZB -->
                    <xsl:variable name="A_R_PartNumber" select = "./PARTN_ROLE" />
                        <Row>
                            <Doc_Number>
                                <xsl:value-of select="node()/IDOC/Z1E1P/Z1BP_ISAORDER/GETDETAILEDLI/BCOAD[position()]/Doc_Number"/>
                            </Doc_Number>
                            <Q_Number>
                                <xsl:value-of select="node()/IDOC/Z1E1P/Z1BP_ISAORDER/GETDETAILEDLI/BCOAD[position()]/Q_Number"/>
                            </Q_Number>
                            <PartNumber>
                                <xsl:value-of select="$A_R_PartNumber"/>
                            </PartNumber>
                        </Row>
                </xsl:for-each>
            </Rows>
</Order>
    </xsl:template>
</xsl:stylesheet>

1 Answer 1

2

try this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
  
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  
  <xsl:strip-space elements="*"/>
  
  <xsl:template match="/">
    <xsl:apply-templates select="Z1E1P/Z1BP_ISAORDER"/>
  </xsl:template>
  
  <xsl:template match="Z1BP_ISAORDER">
    <xsl:apply-templates select="E1EDS01/GETDETAILEDLI/BCOAD">
      <xsl:with-param name="BPARTs" select="BPART"/>
    </xsl:apply-templates>
    
  </xsl:template>
  
  <xsl:template match="BCOAD">
    <xsl:param name="BPARTs"/>
    <xsl:variable name="position" select="position()"/>
    <Row>
      <xsl:copy-of select="Doc_Number"/>
      <xsl:copy-of select="Q_Number"/>
      <PartNumber><xsl:value-of select="$BPARTs[$position]/PARTN_ROLE"/></PartNumber>
      <xsl:copy-of select="$BPARTs[$position]/ADDRESS"/>
    </Row>
  </xsl:template>

</xsl:stylesheet>

EDIT:

After extra info and changed example this is probably what you need:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
  
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  
  <xsl:strip-space elements="*"/>
  
  <!-- Match on  /ORDERS/IDOC, because your result only uses this context.-->
  <xsl:template match="/ORDERS/IDOC">
    <Order>
      <Envelope>
        <Version>1.8</Version>
        <MessageType>
          <!-- Since we only need it once, there is no need to first store it in variable, just use it directly here -->
          <xsl:value-of select="MESTYP"/>
        </MessageType>
        <SenderID>
          <!-- Since we only need it once, there is no need to first store it in variable, just use it directly here -->
          <xsl:value-of select="E1EDKA1[PARVW='KL']/ILNNR"/>
        </SenderID>
      </Envelope>
      <Head>
        <Addresses>
          <!-- In stead of using for-each, use apply-templates with correct predicate, to handle addresses -->
          <xsl:apply-templates select="Z1E1P/Z1BP_ISAORDER/DPART[PARVW='DF']"/>
        </Addresses>
      </Head>
      <Rows>
        <xsl:apply-templates select="Z1E1P/Z1BP_ISAORDER"/>
      </Rows>
    </Order>
  </xsl:template>
  
  <xsl:template match="DPART[PARVW='DF']">
    <Address>
      <City>
        <xsl:value-of select="ORT01"/>
      </City>
      <CountryCode>
        <xsl:value-of select="LAND1"/>
      </CountryCode>
      <MobilePhoneNumber>
        <xsl:value-of select="TELF1"/>
      </MobilePhoneNumber>
    </Address>
  </xsl:template>
    
  <xsl:template match="Z1BP_ISAORDER">
    <xsl:apply-templates select="E1EDS01/GETDETAILEDLI/BCOAD">
      <xsl:with-param name="BPARTs" select="BPART"/>
    </xsl:apply-templates>
    
  </xsl:template>
  
  <xsl:template match="BCOAD">
    <xsl:param name="BPARTs"/>
    <xsl:variable name="position" select="position()"/>
    <Row>
      <xsl:copy-of select="Doc_Number"/>
      <xsl:copy-of select="Q_Number"/>
      <PartNumber><xsl:value-of select="$BPARTs[$position]/PARTN_ROLE"/></PartNumber>
      <xsl:copy-of select="$BPARTs[$position]/ADDRESS"/>
    </Row>
  </xsl:template>
  
</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

4 Comments

Hi, Thank you for the reply! I am getting the below error:- Error at xsl:template on line 269 column 31 XTSE0010: An Z1E1P element must not contain an xsl:template element Error at xsl:template on line 269 column 31 XTSE0010: Element xsl:template must always be a child of xsl:stylesheet or xsl:transform Error at xsl:template on line 274 column 44 XTSE0010: An Z1E1P element must not contain an xsl:template element Error at xsl:template on line 274 column 44 XTSE0010: Element xsl:template must always be a child of xsl:stylesheet or xsl:transform
I tries below: <Doc_Number> <xsl:value-of select="/Z1E1P/Z1BP_ISAORDER/E1EDS01/GETDETAILEDLI/BCOAD[position()]/Doc_Number"/> </Doc_Number> but its always pulling first one.
Your xslt is a lot larger. You can not use a xsl:template inside another. How does the rest look like?
Hi Siebe, I have edited the question and added whole input and xslt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.