Share via


BizTalk Server: Debatching made simple. How to split a message into multiple messages using only XMLReceive pipeline

Scenario

This is a common scenario: An XML message is received and it contains a list of records that we want to split into multiple messages with one record each. 

I have seen many great articles about this. I've found this method to be the simplest, easiest and fastest. 

Solution

Creating an Envelope schema

The only artifact we will have to create to make this work is an Envelope schema. That is to say, a schema for the message that will be received that will contain the list of records we are looking at splitting. 

Using the regular XMLReceive pipeline to debatch your message

Using the XMLReceive pipeline on the receive location will cause the XMLDisassembler to identify your schema as an Envelope schema and trigger it to automatically debatch the original message. That means it will split the original message into multiple messages containing one record only. 

Implementation

We can start from the single record schema or from the multiple record schema. For this example, we will start from the single record schema and create an Envelope schema from it. It is super quick and easy.

Here is what the single record schema we will use on this example looks like:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://ACME.BizTalkProject.Schemas.Product" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://ACME.BizTalkProject.Schemas.Product" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Product">
    <xs:complexType>
      <xs:attribute name="Symbol" type="xs:string" />
      <xs:attribute name="Description" type="xs:string" />
      <xs:attribute name="UOM" type="xs:string" />
    </xs:complexType>
  </xs:element>
</xs:schema>

Lets first create the Envelope schema and then configure it. Create a schema with a name that represents a collection of records. So if your record is called Product, add a schema to your project and name it Products. Rename the default element "Root" to the name of your schema. In this example, we are naming it Products.

At this point your envelope schema will look something like this:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://ACME.BizTalkProject.Schemas.Products" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://ACME.BizTalkProject.Schemas.Products" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Products">
    <xs:complexType />
  </xs:element>
</xs:schema>

Select the <Schema> node on the schema editor and, on the properties window:

  1. Change the Envelope property to True.
  2. Click on the space beside Imports, click on the ellipsis, click Add and select the single record schema. On my example I selected ACME.BizTalkProject.Schemas.Product.

NOTE: If your envelope schema and your single record schema have the same namespace you will need to select Include from the drop-down list available on step 2 above. That will insert the single record schema as a second root node to your envelope schema and will allow you to use this same strategy.

At this point your envelope schema will look something like this:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://ACME.BizTalkProject.Schemas.Products" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns:ns0="http://ACME.BizTalkProject.Schemas.Product" targetNamespace="http://ACME.BizTalkProject.Schemas.Products" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation=".\Product.xsd" namespace="http://ACME.BizTalkProject.Schemas.Product" />
  <xs:annotation>
    <xs:appinfo>
      <b:schemaInfo is_envelope="yes" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" />
      <b:references>
        <b:reference targetNamespace="http://ACME.BizTalkProject.Schemas.Product" />
      </b:references>
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="Products">
    <xs:complexType />
  </xs:element>
</xs:schema>

Select the element you renamed earlier. On my example I selected Products. On the properties window, click on the space beside Body XPath, click on the ellipsis, select the element you are configuring and click OK. That will bring the XPath to that element to the properties window line.

Right click on the element on the schema tree, select Insert Schema Node, select Child Record and hit Enter. Leave the default name on the element.

Select the newly added element and on the properties window:

  1. Click on the space beside Data Structure Type, click on the ellipsis and select the root node from your single record schema from the drop-down list.
  2. Enter unbounded on Max Occurs

The Envelope schema is ready to be used. It should be looking similar to this:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://ACME.BizTalkProject.Schemas.Products" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns:ns0="http://ACME.BizTalkProject.Schemas.Product" targetNamespace="http://ACME.BizTalkProject.Schemas.Products" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation=".\Product.xsd" namespace="http://ACME.BizTalkProject.Schemas.Product" />
  <xs:annotation>
    <xs:appinfo>
      <b:schemaInfo is_envelope="yes" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" />
      <b:references>
        <b:reference targetNamespace="http://ACME.BizTalkProject.Schemas.Product" />
      </b:references>
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="Products">
    <xs:annotation>
      <xs:appinfo>
        <b:recordInfo body_xpath="/*[local-name()='Products' and namespace-uri()='http://ACME.BizTalkProject.Schemas.Products']" />
      </xs:appinfo>
    </xs:annotation>
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="ns0:Product" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Now the XMLDisassembler will know this is an Envelope schema when it looks it up on the BizTalk management database. It will also know which schema to use to debatch it.

Conclusion

You can create a smoke test harness with a receive and a send port using the FILE adapter, drop a message with multiple records in the inbound folder and watch multiple files appear in your outbound folder. 

See Also

Another important place to find an extensive amount of BizTalk related articles is the TechNet Wiki itself. The best entry point is BizTalk Server Resources on the TechNet Wiki.