Skip to Content
Technical Articles

Receiver file adapter: Content conversion for multiple headers and detail lines

Recently went through a question on content conversion for receiver file adapter, where the xml contains multiple header and detail lines. The question is posted hereĀ  –

https://answers.sap.com/questions/10557429/content-conversion-with-deep-structure.html

Worked on this problem via XSLT which saves the pain for content conversion. Using XSLT, we can convert any xml into csv / other text formats without worrying for XML hierarchy

Structure for this example is as mentioned below –

<MT_Invoice>
     <Invoice> 1 to unbounded                (multiple invoices)
           <Header> 1..1                             (1 header)
           <Item> 1 to unbounded               (multiple occurrence)
           <OtherData> 1 to unbounded         (multiple occurrence)
           <Footer>  1..1
    </Invoice>
</MT_Invoice>

Output from the interface should be as mentioned below

HDR;1000057965;9000000618;08/29/2020;                 -- Header
ITM;1000057965;9000000618;000010;50001;               -- Item (multiple) 
ITM;1000057965;9000000618;000010;50001;
ITM;1000057965;9000000618;000010;50001;
ITM;1000057965;9000000618;000010;50001;
OTH;;9000000618;1000057965;;;;                        -- Other Data (multiple)
OTH;;9000000618;1000057965;;;;
FTR;1000057965;9000000618;;;                          -- Footer
HDR;1000057965;9000000618;08/29/2020;                 -- Header   
ITM;1000057965;9000000618;000010;50001;               -- Item (multiple)
ITM;1000057965;9000000618;000010;50001;
ITM;1000057965;9000000618;000010;50001;
ITM;1000057965;9000000618;000010;50001;
OTH;;9000000618;1000057965;;M;;                       -- Other Data (multiple)
OTH;;9000000618;1000057965;;M;;
FTR;1000057965;9000000618;;;                          -- Footer

Source XML data:

 

<MT_Invoice>
	<Invoice>
		<Header>
			<Code>HDR</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<InvoiceDate>08/29/2020</InvoiceDate>
		</Header>
		<Item>
			<Code>ITM</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<LineNo>000010</LineNo>
			<ProductCode>50001</ProductCode>
		</Item>
		<Item>
			<Code>ITM</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<LineNo>000010</LineNo>
			<ProductCode>50001</ProductCode>
		</Item>
		<Item>
			<Code>ITM</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<LineNo>000010</LineNo>
			<ProductCode>50001</ProductCode>
		</Item>
		<Item>
			<Code>ITM</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<LineNo>000010</LineNo>
			<ProductCode>50001</ProductCode>
		</Item>
		<OtherData>
			<Code>OTH</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<InvoiceDate>1000057965</InvoiceDate>
			<ShipTo>100012</ShipTo>
		</OtherData>
		<OtherData>
			<Code>OTH</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<InvoiceDate>1000057965</InvoiceDate>
			<ShipTo>1000057965</ShipTo>
		</OtherData>
		<Footer>
			<Code>FTR</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
		</Footer>
	</Invoice>
	<Invoice>
		<Header>
			<Code>HDR</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<InvoiceDate>08/29/2020</InvoiceDate>
		</Header>
		<Item>
			<Code>ITM</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<LineNo>000010</LineNo>
			<ProductCode>50001</ProductCode>
		</Item>
		<Item>
			<Code>ITM</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<LineNo>000010</LineNo>
			<ProductCode>50001</ProductCode>
		</Item>
		<Item>
			<Code>ITM</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<LineNo>000010</LineNo>
			<ProductCode>50001</ProductCode>
		</Item>
		<Item>
			<Code>ITM</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<LineNo>000010</LineNo>
			<ProductCode>50001</ProductCode>
		</Item>
		<OtherData>
			<Code>OTH</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<InvoiceDate>1000057965</InvoiceDate>
			<ShipTo>1000057965</ShipTo>
			<RouteMethod>M</RouteMethod>
		</OtherData>
		<OtherData>
			<Code>OTH</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
			<InvoiceDate>1000057965</InvoiceDate>
			<ShipTo>1000057965</ShipTo>
			<RouteMethod>M</RouteMethod>
		</OtherData>
		<Footer>
			<Code>FTR</Code>
			<BillTo>1000057965</BillTo>
			<InvoiceNo>9000000618</InvoiceNo>
		</Footer>
	</Invoice>
</MT_Invoice>

 

one option is obviously trying via content conversion or message transformation bean which might need some tricks but knowing XSLT gives an edge here.

This requirement can be achieved via a simple XSLT mapping. The idea behind that is that just print the segments we need in the output and pass to the receiver file adapter as it is. In other words, no need to use the content conversion

 

Here is the XSLT, which would provide us the desired output.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://sap.com/xi/SAPGlobal20/Global">
	<xsl:output method="text" version="1.0" indent="yes"/>
	<xsl:strip-space elements="*"/>
	<xsl:template match="/*">
		<xsl:for-each select="Invoice">
			<xsl:for-each select="Header">
				<xsl:value-of select="Code"/>;<xsl:value-of select="BillTo"/>;<xsl:value-of select="InvoiceNo"/>;<xsl:value-of select="InvoiceDate"/>;
</xsl:for-each>
			<xsl:for-each select="Item">
				<xsl:value-of select="Code"/>;<xsl:value-of select="BillTo"/>;<xsl:value-of select="InvoiceNo"/>;<xsl:value-of select="LineNo"/>;<xsl:value-of select="ProductCode"/>;
</xsl:for-each>
			<xsl:for-each select="OtherData">
				<xsl:value-of select="Code"/>;<xsl:value-of select="BillToCustomerID"/>;<xsl:value-of select="InvoiceNo"/>;<xsl:value-of select="InvoiceDate"/>;<xsl:value-of select="ShipToCustomerID"/>;<xsl:value-of select="RouteMethod"/>;<xsl:value-of select="Recipient"/>;
</xsl:for-each>
			<xsl:for-each select="Footer">
				<xsl:value-of select="Code"/>;<xsl:value-of select="BillTo"/>;<xsl:value-of select="InvoiceNo"/>;<xsl:value-of select="InvoiceDate"/>;<xsl:value-of select="ShipTo"/>;
</xsl:for-each>
		</xsl:for-each>
	</xsl:template>
</xsl:stylesheet>

 

Points to note:

  • I have used semicolon (;) as the field separator here. Any other separator can be used.
  • If field length is to be shortened, XPath function substring can be used to shorten the fields.
  • Similarly spaces can be added using the XPath functions by adding spaces to the fields (Field fixed length type)
  • XSLT can also be adjusted in the receiver file adapter but unit testing is as straight forward in that case as in case of XSLT mapping.

 

Conclusion

Receiver File content conversion has got an escape route and that is XSLT.

Simple or complex, it is a matter of few lines of code in XSLT, rather than a brainstorming in FCC :).

Be the first to leave a comment
You must be Logged on to comment or reply to a post.