The Background:
If
you’ve read any of my blog posts, you’ll know that the
company I work for has implemented a system to process inbound
customer purchase orders into our ERP system using BizTalk Server
2004’s Publish & Subscribe architecture as shown in Figure 1 below.

Figure 1: BizTalk’s Publish & Subscribe Architecture
The Problem:
I
recently needed a means to split these inbound XML documents
into multiple outbound documents where the number of outbound
documents and the content of each document is determined by one of
the fields in the inbound document. For lack of a better term I’m
going to call this a “Logical Splitter” pattern. In
this scenario, I need to split the inbound purchase order document
into multiple outbound sales order documents, one for each
different “RequestedDate” in the line item record as shown in Figures
2, 3 & 4 below. The tricky part is that the header
information needs to be copied into each outbound document,
the appropriate line items need to be copied and the footer
information needs to be recalculated. Not a simple task to
accomplish!

Figure 2: The Inbound Order

Figure 3: One of the Outbound Orders

Figure 4: Another Outbound Order
If you’ve read many BizTalk blogs,
you’ll know that BTS2004 can “debatch” messages using a wide variety of
techniques as explained in Stephen Thomas’ excellent post and downloadable article.
One of the most powerful and flexible of these methods is
debatching using an orchestration as described in Darren Jefford’s blog. I’m
going to use this technique along with some recently learned XSLT magic
to accomplish this without using any external assemblies or custom
pipeline components. To help
simplify the development of this solution, I broke the problem down
into two separate but related programming issues. This post explains
how I accomplished the first and my next post will explain how
I accomplished the second.
- The first is how to write a map that reorganizes one document into
a structure that could be “debatched” using standard BTS2004 debatching
techniques.
- The second is how to write an orchestration to implement this (logical splitting) debatching.
Using External XSLT in the BizTalk Mapper
Besides
using functoids to create your maps, the BizTalk Mapper tool also
allows you to use external XSLT by setting the “Custom XSLT Path”
property as shown in Figure 1 below. This allows you to use XSLT that
may not be possible to create using the standard functoids or the
scripting functoid.

Figure 1: Setting the Custom XSLT Path property
I’ve got to admit in the past few
years I hadn’t run into a situation that required me to use write
any XSLT and frankly, my skills are severely lacking in this area.
So I did what any resourceful developer would do, I asked for HELP!
(Please note, this is not the same as asking for directions which of
course, I would never do) The nice thing is, the XML/XSLT/XPATH user
community is full of great blogs and really helpful folks. There are also some very good tools available on the market such as Altova’s XMLSpy and Progress Software’s Stylus Studio. As always, the folks in the microsoft.public.xml and microsoft.public.biztalk.general pitched in to help also.

Figure 2: The Inbound Schema

Figure 3: The Outbound Schema

Figure 4: XSLT Grouping
What we (I really can’t take much
credit for this) came up with is the XSLT shown in Figure 2 above. The
“key” (no pun intended) is the use of the XSLT key element and key() function along with the XSLT generate-id() function. These allow you to group XML elements based upon a key value in your document, in my case the “RequestedDate” field.
Using An Orchestration to Debatch

Figure 1: Map & Split Orchestration
I’m going to assume that you’ve
created at least one simple orchestration before and skip the basics
such as the “Receive” and “Send” shapes and inbound and outbound ports.
- Once you’ve received a message from a port, you need to
construct a new message using the “Transform” shape as shown above.
This shape enables you to map the fields from the existing message into
the new message using the map created in my last post.

- Next use an “Expression” shape to assign values to
variables used later in the orchestration.
These variables are used to loop through the Order nodes in
my mapped message and to create a new XmlDocument to hold the debatched
messages.

- Next use the “Loop” shape to create a loop until the “Counter”
variable is equal to the number of Order nodes present in the
mapped message.

- After this comes the important step. Use another
“Expression” shape to create the actual debatched messages and
increment the loop counter. This is done using a simple XPath
expression as shown below.

- The next step is to use a “Message Assignment” shape to assign the newly created message from the XmlDocument.

- The final step is to send the debatched message to an outbound port and run through the loop until complete.
This orchestration debatching technique is fairly simple, easy to
understand and very flexible. It’s a great solution to the problem of
logically splitting messages. Download the sample project using the
link below and as always your comments and feedback are welcome.
DOWNLOAD: Logical Splitter Sample Project
Special thanks to Stephen Thomas for his assistance and support!
Special thanks to Jon Flanders at
DevelopMentor for help in providing a work-around for a
little BizTalk compilation bug related to using external XSLT
stylesheets.
