Background

BizTalk let’s you create a map that uses XSLT instead of the functoids/GUI mapping. To do this, you click on the mapping grid, go to the “Grid Properties” window, and put in a filename for the “Custom XSLT Path”. I usually name it the same as the map file, just substituting the .xslt for the .btm file suffix.

In your XSLT file

Take some typical functoid map that uses a C# external library. If you look at the generated XSLT (right click the map and select “Validate”, then open the XSLT file_), you will see something like this:

<pre>
xmlns:ScriptNS0="http://schemas.microsoft.com/BizTalk/2003/ScriptNS0"
</pre>

Actually there will be one of these for each class that you reference.

The actual call to the c# may look like this:

<pre>
   <xsl:value-of select="ScriptNS0:XMLDateToTimeHHMMSS($parmDateTime)"
</pre>

In a normal map, it may be hard to figure out which ScriptNS# correlates to which class/library/.DLL. (Of course you have to reference that .DLL in your References for that project.)

Create your own Custom Extension File

This is where the magic happens! This file ties together your .DLL/classname to the ScriptNS# namespace to be used in your custom XSLT code.

Note: You don’t have to use ScriptNS0. IN the example below, I used ScriptDateFunctions, since the class name is DateFunctions. It doesn’t even have to have the word “Script” in it, but I leave that there to make sure it’s more clear.

<pre>
<ExtensionObjects>  
   <ExtensionObject  
      Namespace="http://schemas.microsoft.com/BizTalk/2003/ScriptDateFunctions"  
      AssemblyName="ABC.Common.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a6349ee3fd01c3ec"  
      ClassName="ABC.Common.Helpers.DateFunctions" />  
</ExtensionObjects>  
</pre>

You can get the AssemblyName, Version, Cultural and Public Key Token from the GAC (Global Assembly Cache). Navigate to your the folder:
c:\windows\microsoft.net\assembly\GAC_MSIL\ABC.Common.Helpers\

Repeat the “ExtensionObject” for each className. Note that if your .DLL has 4 classes, then you would need 4 ExtensionObjects (if you want to call all methods in all 4 classes).

I usually save this as a file called CustomExtension.xml. You could have one for each map, or one shared across all your maps.

Setup the Custom Extension for your Map

Just as you set the “Custom XSLT Path” in a previous step, click on the map grid, go to the “Properties” window, and paste or select your filename for “Custom Extension XML”.

Back to your XSLT

In the xsl:stylesheet root element, make sure you add your namespace:

<pre>
xmlns:ScriptDateFunctions="http://schemas.microsoft.com/BizTalk/2003/ScriptDataFunctions"
</pre>

Make sure the namespace corresponds to the class that contains the method you will call. For example, my “DateFunctions” class has a method called “XMLDateToTimeHHMMSS”.

<pre>
   <xsl:value-of select="ScriptDateFunctions:XMLDateToTimeHHMMSS($parmDateTime)"
</pre>

Test Your Map

Provide a sample instance to test the map. (Click on the .btm file in Solution Explorer), then in the “Properties” window, paste in the name of a file for the “TestMap Input Instance”. Now right click the .btm filename in Solution Explorer, and click “Test Map”. As usual, check for any errors in the “Output” window, and CNTL-Click on the file at the bottom where it says “Output is stored in the following file…”

Possible Errors

Prefix ‘ScriptDateFunctions’ is not defined.
You didn’t include the namespace at the top of your XSLT file.

Summary: We have now used the BizTalk “Custom Extension XML” to allow you to make calls to C# from your custom XSLT maps.