BizTalk 2004 Map. Mapping two input messages into one output message , plus matching content from one message to another.

I have had the problem of having a message such as a Order message, being delivered 
as two separate messages. For example, the Order header Records delivered as one XML message,
and then all the Order Items that belong to Order header Records delivered as a separate XML message.

The two separate messages being delivered look something like below:

Order Headers:

<ns0:Orders Correlator="1" xmlns:ns0="http://IDREFTest.Orders">
  <Order OrderID="6" OrderedBy="BillyBobJim" />
  <Order OrderID="1" OrderedBy="Bob" />
  <Order OrderID="2" OrderedBy="Bobby" />
  <Order OrderID="3" OrderedBy="BobbyJohn" />
  <Order OrderID="4" OrderedBy="BobbyNoItems" />
  <Order OrderID="5" OrderedBy="BillyBob" />
  <Order OrderID="0022" OrderedBy="BillyBobJim" />
</ns0:Orders>
  
  
Order Items:

<ns0:Order Correlator="1" xmlns:ns0="http://IDREFTest.OrderItems">
  <OrderItems OrderID="1" Qty="1" />
  <OrderItems OrderID="1" Qty="11" />
  <OrderItems OrderID="1" Qty="111" />
  <OrderItems OrderID="2" Qty="2" />
  <OrderItems OrderID="2" Qty="22" />
  <OrderItems OrderID="2" Qty="222" />
  <OrderItems OrderID="3" Qty="3" />
  <OrderItems OrderID="3" Qty="33" />
  <OrderItems OrderID="3" Qty="333" />
  <OrderItems OrderID="3" Qty="3333" />
  <OrderItems OrderID="5" Qty="5" />
  <OrderItems OrderID="5" Qty="1" />
  <OrderItems OrderID="5" Qty="11" />
  <OrderItems OrderID="5" Qty="111" />
  <OrderItems OrderID="6" Qty="333" />
  <OrderItems OrderID="6" Qty="3333" />
  <OrderItems OrderID="0022" Qty="3" />
  <OrderItems OrderID="0022" Qty="33" />
</ns0:Order>

My goal then was to create a final Order XML Message that looks like the below (combining
information from the two messages into one message, plus also matching the correct order items with
the correct order headers). I wanted to accomplish this by just using BTS maps and functoids
that are installed with BTS2004.

<ns0:Orders xmlns:ns0="http://IDREFTest.OrdersandOrderItems">
 <Order OrderedBy="BillyBobJim" OrderID="6">
    <OrderItems OrderID="6" Qty="333" />
    <OrderItems OrderID="6" Qty="3333" />
</Order>
 <Order OrderedBy="Bob" OrderID="1">
    <OrderItems OrderID="1" Qty="1" />
    <OrderItems OrderID="1" Qty="11" />
    <OrderItems OrderID="1" Qty="111" />
 </Order>
    <Order OrderedBy="Bobby" OrderID="2">
    <OrderItems OrderID="2" Qty="2" />
    <OrderItems OrderID="2" Qty="22" />
    <OrderItems OrderID="2" Qty="222" />
  </Order>
  <Order OrderedBy="BobbyJohn" OrderID="3">
     <OrderItems OrderID="3" Qty="3" />
     <OrderItems OrderID="3" Qty="33" />
     <OrderItems OrderID="3" Qty="333" />
     <OrderItems OrderID="3" Qty="3333" />
  </Order>
 <Order OrderedBy="BobbyNoItems" OrderID="4" />
 <Order OrderedBy="BillyBob" OrderID="5">
     <OrderItems OrderID="5" Qty="5" />
     <OrderItems OrderID="5" Qty="1" />
     <OrderItems OrderID="5" Qty="11" />
     <OrderItems OrderID="5" Qty="111" /> 
  </Order>
 <Order OrderedBy="BillyBobJim" OrderID="0022">
     <OrderItems OrderID="0022" Qty="3" />
     <OrderItems OrderID="0022" Qty="33" />
 </Order>
</ns0:Orders> 

Therefore to accomplish this:

1) Created an Orchestration that contains a parallel convoy, that correlates on
the Correlator attribute on both the Orders.xsd and OrderItems.xsd properties.

2) Created a Map with two inputs (Order Header and Order Items) and one output (OrdersAndOrderItemsAll). 
To create a map with multiple inputs and outputs, create the needed messages
in the Orchestration View. For example , in this case an OrdersOnly message,
OrderItemsOnly Message and the OrdersAndOrderItemsAll Message.
Drop a transform shape on your orchestration and then choose the source(input) message(s).
In this case there are two : OrdersOnly message and OrderItemsOnly message.
Choose the destination(output) message(s) : OrdersAndOrderItemsAll message.
In the Transform Configuration dialog box, choose -> new map. In this case
a new map is created that looks like the below (minus any of the links and functoids between source and
destination messages). These were put in later.

 


3) In the map as above, links and two looping functoids were used to create an interim message (OrdersAndOrderItemsAll)
All OrderHeader records will contain all the OrderItem records.

4) Create another map that looks like the below, using the OrdersAndOrderItemsAll message as the source and using a new
message OrdersAndOrderItems as the destination. The equal functoid is used to include only the correct orderitems with each
order header. This map creates the desired resultant xml instance.

 

Download the complete solution Here.

What I like about this solution, is that it works. What I don't like about this solution is the interim message, with each order header message
including all the order items. In my case the incoming OrderHeader message and OrderItem messages were not terribly large, therefore
the interim message was not huge. Of course there may be other ways to accomplish this, possibly using custom xslt.