Splitting Delimited Values in BizTalk Maps

Today, one of our BizTalk developers asked me how to take a delimited string stored in a single node, and extract all those values into separate destination nodes.  I put together a quick XSLT operation that makes this magic happen.

So let’s say I have a source XML structure like this:

I need to get this pipe-delimited value into an unbounded destination node.  Specifically, the above XML should be reshaped into the format here:

Notice that each pipe-delimited value is in its own “value” node.  Now I guess I could chained together 62 functoids to make this happen, but it seemed easier to write a bit of XSLT that took advantage of recursion to split the delimited string and emit the desired nodes.

My map has a scripting functoid that accepts the three values from the source (included the pipe-delimited “values” field) and maps to a parent destination record.

Because I want explicit input variables  to my functoid (vs. traversing the source tree just to get the individual nodes I need), I’m using the “Call Templates” action of the Scripting functoid.

My XSLT script is as follows:

<!-- This template accepts three inputs and creates the destination 
"Property" node.  Inside the template, it calls another template which 
builds up the potentially repeating "Value" child node -->
<xsl:template name="WritePropertyNodeTemplate">
<xsl:param name="name" />
<xsl:param name="type" />
<xsl:param name="value" />

<!-- create property node -->
<!-- create single instance children nodes -->
<Name><xsl:value-of select="$name" /></Name>
<Type><xsl:value-of select="$type" /></Type>

<!-- call splitter template which accepts the "|" separated string -->
<xsl:call-template name="StringSplit">
<xsl:with-param name="val" select="$value" />

<!-- This template accepts a string and pulls out the value before the 
designated delimiter -->
<xsl:template name="StringSplit">
<xsl:param name="val" />

<!-- do a check to see if the input string (still) has a "|" in it -->
  <xsl:when test="contains($val, '|')">
   <!-- pull out the value of the string before the "|" delimiter -->
   <Value><xsl:value-of select="substring-before($val, '|')" /></Value>
     <!-- recursively call this template and pass in 
value AFTER the "|" delimiter -->
     <xsl:call-template name="StringSplit">
     <xsl:with-param name="val" select="substring-after($val, '|')" />

      <!-- if there is no more delimiter values, print out 
the whole string -->
      <Value><xsl:value-of select="$val" /></Value>


Note that I use recursion to call the “string splitter” template and I keep passing in the shorter and shorter string into the template.   When I use this mechanism, I end up with the destination XML shown at the top.

Any other way you would have done this?

Technorati Tags:


Categories: BizTalk

6 replies

  1. Great post Richard. I would also implement it like that. It is somewhat similar with Greg’s solution to this post:


  2. Thanks, Richard. I started with your template and made a couple modifications to it, specifically when the delimited value contains no items.


  3. Exactly what I needed! Thanks for posting this.

  4. You rock Richard! Perfect!

  5. I have different requirement.

    input file


    Output expected.




Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: