I’m creating a new series of posts related to using the BizTalk Mapper.  I know,
it’s certainly less sexy than Pipeline Testing Framework (seriously, follow that link)
or many other BizTalk subjects, but so much of the magic of BizTalk happens in the
mapping.

In my experience, when people are introduced to the BizTalk Mapper they get it very
quickly.  The user interface is straight forward for most of
what you need to do in mapping output.  But certainly not all.  Take for
example some data that looks like this :

<?xml version=”1.0″ encoding=”utf-8″ ?>

<MyRoot>

  <ref qualifier=”D2″ value=”999999999″ />

  <ref qualifier=”XX” value=”999999999″ />

  <ref qualifier=”ZZ” value=”XX-YYYYYYYY” />

  <nm qualifier=”NI” value=”999999999″ />

</MyRoot>

 

Your mission, should you choose to accept it is simple.  Output one and only
one value to destination schema in a node called Identifier which contains either
the value of the ‘value’ attribute of the ‘nm’ element if the matching qualifier is
‘ZZ’ or if that does not exist the ‘value’ attribute of any ‘ref’ element containing
a ‘qualifier’ attribute of ‘ZZ’.  If neither exists, then output the constant
value ‘N/A’.

The catch?  Both nodes can both exist with the proper qualifier,
and ‘nm’ must take precedence in that case.

Now, I’ve no doubt at all that someone could come up with some combination of functoids
which might solve this problem.  But we must remember that in the end a map is
just XSLT and this problem is supremely easy in XSLT and extremely difficult with
the mapper.  The solution, as you’ve likely already guessed, is an XSLT Call
Template Scripting Functoid.

An XSLT Call Template Scripting Functoid lets you inject your own XSLT into the middle
of a map.  No need to take the effort of writing the full XSLT yourself if only
one or two mappings are giving you trouble.  Obviously to be able to write such
a functoid you need to understand XSLT, which if you are mapping is a good skill to
have anyway.  In this simple example we don’t even have to deal with parameters. 
By entering a template as follows, you can solve this problem in a few short lines.

  <xsl:template name=”MapIdentifier”>

    <xsl:variable name=”nmValue” select=”/MyRoot/nm[@qualifier=’ZZ’]/@value”
/>

    <xsl:variable name=”refValue” select=”/MyRoot/ref[@qualifier=’ZZ’]/@value”
/>

    <xsl:element name=”Identifier”>

      <xsl:choose>

        <xsl:when test=”$nmValue”>

          <xsl:value-of select=”$nmValue”/>

        </xsl:when>

        <xsl:when test=”$refValue”>

          <xsl:value-of select=”$refValue”/>

        </xsl:when>

        <xsl:otherwise>N/A</xsl:otherwise>

      </xsl:choose>

    </xsl:element>

  </xsl:template>

 

Some things to remember when working with XSLT Call Templates.

  1. Only use these when needed.  I recently heard Roy Osherove give the same advice
    regarding Regular Expression and he was right.  Both RegEx and XSLT Call Templates
    are more cryptic and harder for someone coming after you to decipher.  Use them
    when you must, when they save you time, but don’t lean on them for everything.
  2. The Template name must be unique within the map.  If you copy-paste the template
    and don’t change the name then only one version will be run.  If you later modify
    one of them and start going nuts trying to figure out why the second isn’t behaving
    properly, check your names.
  3. XSLT Call Templates must create the destination node.  Element or Attribute they
    don’t care, when you write one of these you are taking on the job of outputting that
    node, namespace and all. 

I hope this has been a good quick primer on using XSLT Call Templates.  If you’ve
got a topic you’d like covered, leave a comment!

[Post Script : Before anyone comments, the example XML given was deliberately
rendered similar to an EDI structure because this is a common problem in EDI mappings.]