Ok, this will be my third mapping problem published and I can tell that it will not be the last…
First of all let me tell you that for me there is no perfect solution to solve a particular mapping problem, often there are several ways to solve the problem and how it’s solved always depends on the experience and knowledge that you have with the tool or/and with XSLT (of course sometimes there are some solutions better than others or with higher performance)
Today Nicolas asked if I could help him with this particular problem and after talking with him we decided to publish the solution here so that it can help others with similar problems.
Problem
We want to combine data from two different messages into one, more specifically, we want to combine each user with his address and each user can have multiple addresses.
This is the transformation screenshot:
A sample of Users Input message:
<ns0:Users xmlns:ns0="http://BizTalk_Server_GenerationFichiersReleve.test"> <User> <UserID>1</UserID> <LastName>Nicolas</LastName> <FirstName>Brun</FirstName> </User> <User> <UserID>2</UserID> <LastName>Philippe</LastName> <FirstName>Picard</FirstName> </User> </ns0:Users>
A sample of AddressesInput message:
<ns0:Addresses xmlns:ns0="http://BizTalk_Server_GenerationFichiersReleve.Test2"> <Address> <UserID>1</UserID> <AddressLine1>245 rue françois 1er </AddressLine1> <PostCode>69001</PostCode> <Town>Lyon</Town> </Address> <Address> <UserID>2</UserID> <AddressLine1>18 avenue Gerard Majax</AddressLine1> <PostCode>75001</PostCode> <Town>Paris</Town> </Address> <Address> <UserID>2</UserID> <AddressLine1>450 rue Michou</AddressLine1> <PostCode>75005</PostCode> <Town>Paris</Town> </Address> </ns0:Addresses>
A sample of the expected result:
<ns0:Addresses xmlns:ns0="http://BizTalk_Server_GenerationFichiersReleve.Test2"> <Address> <UserID>1</UserID> <AddressLine1>245 rue françois 1er </AddressLine1> <PostCode>69001</PostCode> <Town>Lyon</Town> </Address> <Address> <UserID>2</UserID> <AddressLine1>18 avenue Gerard Majax</AddressLine1> <PostCode>75001</PostCode> <Town>Paris</Town> </Address> <Address> <UserID>2</UserID> <AddressLine1>450 rue Michou</AddressLine1> <PostCode>75005</PostCode> <Town>Paris</Town> </Address> </ns0:Addresses>
As I said earlier, there are several ways to solve a particular mapping problem, this is the solution I like!
Solution
The first part is a normal drag-and-drop mapping problem, however, decided to create a template to map the second part of the message (addresses), using a scripting functoid with an inline XSLT call-template with the following code:
<xsl:template name="AddressTemplate"> <xsl:param name='id' select='UserID'/> <Addresses> <xsl:for-each select="../../../InputMessagePart_1/s0:Addresses/Address[UserID=$id]"> <Address> <UserID> <xsl:value-of select="UserID/text()"/> </UserID> <AddressLine1> <xsl:value-of select="AddressLine1/text()"/> </AddressLine1> <PostCode> <xsl:value-of select="PostCode/text()"/> </PostCode> <Town> <xsl:value-of select="Town/text()"/> </Town> </Address> </xsl:for-each> </Addresses> </xsl:template>
You can download the source code from:Grouping elements from different messages in BizTalk Maps
GitHub