Using XSLT Templates in Maps and General Thoughts on the BizTalk Server Mapper
In this post I will describe using XSLT templates in maps followed by a general discussion on the BizTalk mapper per se (since the release of Windows Azure BizTalk Services I guess I should qualify what mapper I am referring to now: this is the BizTalk Server 2013 mapper :-)).
For further information on XSLT, please refer to this link.
An XSLT template defines a set of transformation rules that can be applied to a specific set of nodes. It’s possible to define and execute a template in the mapper itself using the scripting functoid.
In the example that follows, the BizTalk solution processes expense claims from employees. However, due to a company “healthy lifestyle” programme, any purchases of Moro bars needs to referred to the employees manager, so they can be given a stern talking too in an attempt to discourage there consumption! (For non Kiwis, a Moro bar is much like a Mars bar but more delicious :-)).
So if a transaction has a <Description> equal to “Moro bar” in the source schema, the <ReferYN> element in the destination schema should be set to “Y” (to indicate “Yes – this employee needs to be referred to his manager”) otherwise it should be set to “N” (to indicate “No – this employee doesn’t need to be referred to his manager”).
1. Drag a scripting functoid onto the map surface. I make it a practice to set the input to the functoid to the root element of the source schema, although this isn’t required to execute the template. This prevents an annoying warning message when Visual Studio 2012 compiles the map indicating that the scripting functoid has no input parameters.
2. Double click on the functoid and click on the “Script Functoid Configuration” tab. Select script type “Inline XSLT Call Template”:
3. It’s possible to write your XSLT directly in the “Inline script” field and I find that this is ok for simple scripts but I prefer to write my XSLT in a file and import using the “Import from file …” button:
In a nutshell, this script outputs a <ReferYN> element depending on the number of transactions with the description “Moro bar”. If the number of transactions is greater than one, the value “Y” is outputted or the value “N” is outputted.
Note that a “match” attribute can be added to the <template> element to explicitly specify what nodes the template will be applied against (further information on this is available here).
4. Don’t forget to add a short and descriptive “Label” describing the function of the functiod and also a brief set of comments for the next developer:
Here is a screenshot of the original ExpenseClaim message:
And this is what it looks like after passing through the map:
I hope this explanation sufficiently gets across how useful XSLT templates are in maps. Often using a template reduces the number of functoids needed to generate the desired result in the destination XML. Less code is a characteristic of functional programming (compared to imperative programming) and XSLT fits this definition in some respects. As maps become more complex and contain greater amounts of logic, using templates is a good option for making a map more readable and less cluttered.
In the example above for instance, without using the template a looping functoid would have been required and also some if-then-else construct. Rather than doing this, just defining a straight function is a better option I believe.
Having said all this, if a map starts to get very complicated, I usually dump the mapper altogether and dive straight into the XSLT and reference this in the BizTalk map via the “Custom XSLT Path” property (further information on this is available here on MSDN).
General Thoughts on the BizTalk Mapper
My beef with the mapper is that is doesn’t encourage a functional approach to writing XSLT (which is it’s power and what I like about it). When reading sources indicating that the mapper generates inefficient and poorly written XSLT I believe that the design of the mapper encourages this and that the generated XSLT is actually partly a result of the imperative mindset that the mapper promotes in the developer. This is particularly apparent in the overuse of loops in maps (again the developer is thinking in the imperative style) when a straight function would do (like the XSLT template example above).
So I think the mapper is not a good tool for writing XSLT. However it is extremely popular and I know used by lots of developers so it will always be part of the BizTalk toolset.
I would be really interested in the opinions of other developers on the (mis)use of the mapper :-).