Using custom XSLT in BizTalk
Over the last 3 years I’ve started using custom XSLT to a greater extent than previously. Today, my default choice of option is undoubtedly custom XSLT, and I demand very convincing arguments, such as “business employees without any developer skills are responsible for creating a lot of very simple mappings”, before I recommend dragging Functoids to the grid.
Without further discussion of the pros and cons of the BizTalk mapper and Custom XSLT, I’ll step through the approach of my own, when doing custom XSLT in BizTalk.
1. Getting started
If you are familiar with the mapper and just started using custom XSLT, you might need to change your mind set a bit. Your job with XSLT is to write the output. Please forget the concept of dragging a source element into a destination element. Instead, focus on writing the destination message, and know that you can query into the source document as the output is being written.
First, create your BTM, and then your XSLT(to get it into your BizTalk project, you’ll need to save the file, and add existing item on the BizTalk project). I like to keep the names identical:
As usual we need to pick the source and destination schemas in the BizTalk mapper. Additionally for custom XSLT, we need to select the path for the .xsl file. Left-click the grid and browse the .XSL file in the property Custom XSLT Path. Once an .XSL file path has been applied, the mapper will ignore any content in the BizTalk mapper and use the XSLT instead.
2. The XSLT – setting up namespaces and making the first xpath query
In almost any case I declare all the namespaces within the stylesheet header, even if it’s only used a very few times in the XSLT, because it gives good overview (at least to me) to have them up there.
Now we can actually start the mapping – here’s the first couple of lines in the output:
If you are not a fan of <xsl:element> and want to write the output elements explicitly, remember to add the source namespaces to the exclude-result-prefixes attribute.
3. The XSLT – calling inline .NET methods
Usually, I opt for external assemblies, when I need to execute .NET code from within the XSLT. However, I recognize two advantages for inline.
1. Debugging the XSLT is possible in Visual Studio with inline .NET method calls. On the contrary when introducing an external assembly, the ability to debug the XSLT in Visual Studio is lost and you will need to uncomment the calls if you need to do so, which is pretty annoying. So that is a big advantage for inline .NET methods.
2. Dependency and deployment is, depending on your architecture and what you are trying to achieve, a potential downside if you introduce an external assembly to service a map. The inline approach will be compiled as part of the map assembly, which makes it very quick and simple to deploy.
To do inline .NET methods you must do two things to setup the method:
1. Add the following namespace to the stylesheet:
2. Define the method like this. For this example, I’m using a method to convert date formats.
Now you can call the method like this:
4. XSLT – Calling external .NET methods
Despite the disadvantages mentioned earlier, external assemblies are the superior choice compared to inline .NET methods, because of these two:
First off you need to GAC your external assembly and make a reference to the external assembly from your mapping project.
Next, you’ll need to create a Custom Extension XML file containing the extension objects, a list of the external assemblies that you want to use from your Custom XSLT mappings.
The Custom Extension XML file looks like this:
For each class in every external assembly, you’ll have to declare an ExtensionObject element with those three attributes:
– Namespace: To be used in the XSLT to point to this extension object. Must be unique within a Custom Extension XML file.
– AssemblyName: The fully qualified assembly name.
– ClassName: The class name in the assembly.
You will be able point to that single Custom Extension XML file from all of your maps if necessary, and you don’t need deploy the Custom Extension XML file, because its configuration will be compiled into your mapper project just as the XSLT when you point to the Custom Extension XML file from your map properties:
Now with the external assembly and Custom Extension XML file in place, lets look at the XSLT again. In the XSLT you need to point to the ExtensionObjects. As mentioned above it’s possible to point at several ExtensionObjects as long as the ExtensionObject is defined in the Custom Extension XML file. You point to an ExtensionObject from with the XSLT like this:
The XSLT points to the ExtensionObject using the namespace attribute, and the ExtensionObject has details on the .dll, thus rounding up the reference from you custom XSLT to the external assembly.
Finally, the .NET method in the external assembly is called by using the same syntax as inline calls:
Hopefully, the above has supplied your xml and xpath skills with enough information to throw away the BizTalk mapper in favor of time saving, clean, well-structered and powerful custom XSLT mappings.