Introduction
The BizTalk Mapper is an integral part of the BTS toolkit and, depending on your inclination
and experience, you will probably either love, hate it, or not care about it.
At its core, the BizTalk Mapper is simply a visual tool for specifying XSLT (eXtensible
Stylesheet Language Transformations).
This XSLT is used to transform one stream of XML data into another stream of XML data.
And since a “stream of XML data” = “message in BizTalk”, this means transforming one
message into another message.
[Aside: you might think that the Mapper allows you to specify multiple source
or destination messages, but this is actually a trick – BizTalk creates a special
schema with one part per input/output message – there’s still only one input/output
message]
How well the BizTalk Mapper performs its task depends on the complexity of the transformation
you’re attempting – and the skill/experience of the developer using the BizTalk Mapper!
Download the complete series as a single Microsoft
Word document (1.2MB) or Adobe
PDF document (620kb).
BizTalk Mapper 101
The Mapper presents you with source and destination panes, displaying your source/destination
schemas in a tree view.
You then link source elements/attributes to destination attributes/elements, optionally
using functoids to perform an operation.
A large collection of default functoids are included, and you can write your own functoids
if the operation you’re performing isn’t included.
One of the functoids (the Script functoid) allows you to directly type in XSLT/C#/VB.NET/JScript
or specify a .NET assembly to call to perform an operation.
Additionally you can specify your own XSLT file to use if you have one (e.g. if you
use Altova
MapForce or Stylus Studio to
maintain XSLT) – this will replace anything the Mapper would generate.
History
The BizTalk
Mapper was originally unveiled with BizTalk Server 2000.
In its original incarnation, the Mapper was a separate executable, which worked hand-in-hand
with the BizTalk
Editor.
A developer would use the BizTalk Editor to create a specification (analogous to a
schema in today’s BizTalk), and then use the BizTalk Mapper to map from one specification
to another.
A specification was an XDR (Xml-Data
Reduced) representation of a document.
XDR specifications could represent DTDs, XML docs, EDI docs, flat files, etc. by noting
the position of the elements within them (by comparison, BizTalk Server from v2004
onwards uses XSDs (Xml
Schema Definition) to accomplish the same task).
BizTalk could convert from a source format to an Xml Document (and vice versa) by
referencing the XDR specification.
The XSLT generated by the BizTalk Mapper would convert (map) one Xml Document into
another Xml Document, and this Xml Document would then be converted into the destination
format via the XDR.
The BizTalk Mapper from BTS 2000/2002 would look very familiar to current BizTalk
developers – most of the functoids we use are all there, as is the familiar source/destination
grid:
BizTalk Mapper circa 2002 (click for a larger view)
Under the covers, however, the Mapper was predominantly VBScript based.
Most of the functoids used VBScript to perform the functions, and the script functoid
only allowed you to type in VBScript (or JScript in BTS 2002).
One thing about the Mapper never changed though: it was used to generate XSLT, which
in BTS 2000/2002 was consumed by the MSXML 3.0 parser to perform transforms.
BizTalk Mapper in BTS 2004 / 2006 / 2006R2
The Mapper present in BizTalk since 2004 still performs the same functions. In fact
it looks very similar, and even has the same functoids (along with some new ones).
However there are some important differences:
What happens when a map is compiled
When the project containing your map is built, the compiler does the following:
The generated class is what is used to perform the translation.
If you disassemble the class (here using .NET
Reflector) you’ll see something like this:
What’s interesting here is that the XSLT is stored as strings – and is repeated: once
in a member variable at the top, and then again as a string literal in the XmlContent property
(I would imagine that this is a bug in the compiler, and that the XmlContent property
is supposed to return the value of the _strMap member
variable – but who knows!).
What’s important to note is that the XSLT is not compiled in any sense of the
word.
That doesn’t happen until you execute the map.
Important Note: If you use the Custom XSL Path property on a map file
(to specify an external XSLT file) then the contents of that XSLT file are what appear
in the above class – that is, there is no link to the file: instead the contents are
copied into the class. In fact, once compiled you can’t tell from looking at the class
whether the XSLT was from an external file, or created by the BizTalk Mapper.
What happens when a map is executed
Ultimately, all current version of BizTalk use the .NET 1.x XslTransform class
to perform transformations.
(note that if you click on that link to go to the MS documentation there’s a big warning
saying:
NOTE: This API
is now obsolete.
That’s because the XslTransform class
was replaced with the XslCompiledTransform class
as of .NET 2.0. More on this later…)
The Transform property looks like this:
(I’m glossing over the fact that there is also a ScalableTransform property
which returns a Microsoft.BizTalk.ScalableTransformation.BTSXslTransform object
– which allows for messages to be streamed to/from disk if they’re over a certain
size – see here for
more information).
When BizTalk calls the Transform property
(for example, when executing a map inside of an orchestration, in which case the XslTransform.Transform() method
is called by the Microsoft.XLANGs.Core.Service.ApplyTransform() method)
the above code is executed to load your XSLT into an instance of an XslTransform class.
Note: The XslTransform.Load() method
is called using the current Assembly’s evidence – this causes the XSLT to be regarded
as fully trusted, indicating that any inline scripts will be run with full permissions.
All that BizTalk has to do now is call XslTransform.Transform() to
perform the transformation, passing in the source message and an XsltArgumentList parameter
(containing instances of any classes/types used by the XSLT e.g. classes specified
in external assemblies) and the Transform() method
will return an output stream containing the transformed message.
XslTransform vs XslCompiledTransform
As mentioned above, all current flavours of BizTalk since BTS 2004 use the obsolete XslTransform class
to perform transformations.
However, .NET 2.0 introduced the new XslCompiledTransform class
for performing transformations
There are many differences between the two, but to my mind the two most important
features introduced by the new class are:
In a lot of cases, XslCompiledTransform will
significantly outperform XslTransform for
the same XSLT.
The caveat is that because the XSLT is compiled to MSIL, the first time the transform
is run there is a perf hit, but subsequent execution should be a lot faster.
For a detailed look at the perf differences between the two classes (plus comparisons
with other XSLT processors) have a look at this
post.
BizTalk doesn’t support the XslCompiledTransform class
at all. If you’ve ever tried to validate a real-world schema in BizTalk and had it
fail because it doesn’t load in the imports/includes (usually when you leave the Validate
TestMap Input/Output option checked when using the Test Map functionality),
then you’re probably aware of this already…
At the moment, the only way to use the XslCompiledTransform class
in BizTalk is to implement it yourself and call it from an orchestration.
XSLT v1.0 vs XSLT v2.0
I can’t finish this post without a brief note about this: BizTalk (up to 2006 R2)
only supports XSLT v1.0.
XSLT v2.0 has a lot more functionality in it, but you can’t use this in your maps
as there is currently no support in .NET for XSLT v2.0 – and
there is unlikely to ever be any (and see here).
At the moment if you want to use XSLT 2.0 in .NET (or BizTalk) you have to use an
external XSLT processor – something such as SAXON (or
see here for the open-source
version).
You would then have to roll your own class to use this, and use the class from within
an orchestration – meaning you can only use XSLT 2.0 from within orchestrations, and
not from receive/send ports.
XSLT 2.0 provides a much richer set of operations/functionality and would mean that
there wouldn’t be such a need to drop out to assemblies/inline code for more complex
operations.
But I suspect that Microsoft is more likely to introduce either XQuery or LINQ
to XML support in a future version of the BizTalk Mapper.
The next ten posts will cover the default functoids which come with the BizTalk Mapper.