Does BizTalk Server maps have patterns? What are patterns? Wikipedia states that it’s a pattern if
“…it happens 5 or more times…”
and that a design pattern in computer science
“…is a general reusable solution to a commonly occurring problem…”
To summarize, the solution that I’m going to present is certainly something that I’ve been up against a number of times, and its something that’s really quite useful, yet simple, and something that the BizTalk mapper does really well. It’s the task of data concatenation, or appending data if you’d rather call it that. It’s an implementation of the content enricher pattern.
Say that you have two schemas, for simplicity, lets call them Schema1 and Schema2. Now both of them are based on a kind of name/value looping structure. What you would like to do is to append the name/value pairs in Schema2 to the recurring record in Schema1 and produce a new, enriched schema.
In Schema1, Record is repeating, and in Schema2, Row is repeating.
Now how do you combine that. That answer is… easily.
Now to do this combining you have to use an orchestration, since you can’t do a map with multiple inputs outside an orchestration. So we create an orchestration, get our messages created, and create a map and make it take two inputs, that is, we drop a transform shape, double click it and assign two input messages, and one output, like so:
After you open the map created, you will have two message parts under the root, like so:
Now we can do the mapping:
As always, the best way to check that the map really does what you are after is to look at the xslt generated. I’m not going to paste the entire xslt generate here, but if we take it down to just the important part, it’s this:
<ns0:Root><Header />...<Records><xsl:for-each select="InputMessagePart_0/ns0:Root/Records/Record" />...<xsl:for-each select="InputMessagePart_1/s0:Root/Rows/Row" />...</Records></ns0:Root>
The map we created will loop first the Record records, and then the Row records, and for each such found it will output (not shown) the Record record with a Name and Value.
Just so there is no misunderstanding, here are sample documents. First the xml sent in (the combination of two xml messages conforming to the two schemas)<ns0:Root xmlns:ns0="http://schemas.microsoft.com/BizTalk/2003/aggschema"><InputMessagePart_0><ns1:Root xmlns:ns1="http://MappingConcatenation.Schema1"><Header><ID>ID_0</ID></Header><Records><Record><Name>Name_1</Name><Value>Value_1</Value></Record></Records></ns1:Root></InputMessagePart_0><InputMessagePart_1><ns2:Root xmlns:ns2="http://MappingConcatenation.Schema2"><Rows><Row><Name>Name_2</Name><Value>Value_2</Value></Row></Rows></ns2:Root></InputMessagePart_1></ns0:Root>
and then the result:<ns0:Root xmlns:ns0="http://MappingConcatenation.Schema1"><Header><ID>ID_0</ID></Header><Records><Record><Name>Name_1</Name><Value>Value_1</Value></Record><Record><Name>Name_2</Name><Value>Value_2</Value></Record></Records></ns0:Root>
For those saying that what I’ve done is nothing special. You are quite right, it’s not, but it’s a very useful pattern.