Skip to Content
I’ve faced the problem of creating XSLT multi-mapping. We can not use Message Mapping  in some cases (flexible structure messages, etc). This blog contains an example to solution I have found. *0.Problem statement* We have two source messages of *MT_A* and *MT_B* types: image image Number of rows in *MT_A* is equal to number of items to *MT_B*. And we need to combine them into one target message of *MT_C* type: image   | | MT_C/row[+i+]=MT_B/item[+i+] MT_C/row[+i+]/CALYEAR=MT_A/row[+i+]/CALYEAR MT_C/row[+i+]/Data1=MT_B/item[+i+]/Data1 MT_C/row[+i+]/Data2=MT_B/item[+i+]/Data2 *1.Message mapping solution* First, let’s create Message Mapping to see additional elements *Messages* and *Message1* in the target message. These elements are nessesary in multi-mapping. XSLT mapping must create them too. image | /ns0:Messages/ns0:Message1/ns1:MT_C/row=/ns0:Messages/ns0:Message2/ns1:MT_B/item /ns0:Messages/ns0:Message1/ns1:MT_C/row/CALYEAR=/ns0:Messages/ns0:Message1/ns1:MT_A/row/CALYEAR /ns0:Messages/ns0:Message1/ns1:MT_C/row/Data1=/ns0:Messages/ns0:Message2/ns1:MT_B/item/Data1 /ns0:Messages/ns0:Message1/ns1:MT_C/row/Data2=/ns0:Messages/ns0:Message2/ns1:MT_B/item/Data2 | Operation mapping : image  Successiful message mapping test: image Now we have got the xml structure of result with *Messages* and *Message1* elements: image *2.XSLT solution *

This XSLT code generates results equal to Message Mapping above: 


<*xsl:stylesheet* version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <*xsl:template* match="/"> <*xsl:apply-templates* select="//item"/> </*xsl:template*> <*xsl:template* match="item"> <*xsl:variable *name="rownum">
<*xsl:number* value="position()" format="1"/> </*xsl:variable*> <*xsl:apply-templates* select="//row"> <*xsl:with-param* name="rownum"><*xsl:value-of select*="$rownum"/></*xsl:with-param*> </*xsl:apply-templates*> <*xsl:value-of select*="Data1"/><*xsl:value-of select*="Data2"/> </*xsl:template*> <*xsl:template* match="row"> <*xsl:param *name="rownum">0</*xsl:param*>

<*xsl:choose*>
<*xsl:when* test="position()=$rownum"> <*xsl:value-of select*="CALYEAR"/> </*xsl:when*> </*xsl:choose*> </*xsl:template*> </*xsl:stylesheet*> I create a variable "*rownum*" to count current number of target message row.  This construction sends this variable to template responsible for elements *row* from *MT_A*: | | <*xsl:with-param* name="rownum"><*xsl:value-of select*="$rownum"/></*xsl:with-param*> In this template we need to init used variable with | | <*xsl:param* name="rownum">0</*xsl:param*>

And this construction sets * MT_C/row[+current row+]/CALYEAR=MT_A/row[+variable rownum value+]/CALYEAR*:

<*xsl:when* test="position()=$rownum"> </*xsl:when*> Xsl file must be archived with ZIP and uploaded in SAP PI using Imported Archive: image Operation mapping must be changed:  image After test in Operation mapping you can see successiful result: image
To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply