In this section:
Transformation Choices
BizTalk Mapper
Custom XSLT with the BizTalk Mapper
External Transform Engine
Transformation in code
Which one should you use?
Transformation Choices
When performing transformations in BizTalk, you have four
choices (that I can think of):
- Using the BizTalk Mapper
- Using a custom XSLT file with the BizTalk Mapper
- Using a separate transformation engine (called from code)
- Performing transformations in code
Each of these offers their own benefits depending on your
requirements.
Normally your choice will depend on 3 factors:
- Performance
- Complexity
- Maintainability
Generally you will get one (or two) of these, at the cost of
the third.
For simple transformations, you can get all three with the
Mapper using the built-in functoids.
In order to decide if the BizTalk Mapper is the best choice,
we have to look at these alternatives and compare them.
BizTalk Mapper
The BizTalk Mapper is the de-facto standard for
transformations in BizTalk.
With this option I'm including maps created via the Mapper
visual designer – I'm not including maps which reference external XSLT.
Maps created with the designer include those which use:
- No functoids, or only functoids which emit XSLT
- Default functoids
- Custom functoids / Script functoids with referenced
assemblies
- Script functoids with inline C#/VB/JScript
- Script functoids with inline XSLT
If you're creating a map which is relatively simple (e.g.
has less than 40 or so links, and less than 20 functoids) then you could argue
that the map is easy to follow and maintain.
If your map has no functoids, or only uses functoids which
emit XSLT, then your map will likely perform very well.
If you're only processing a small number of messages (e.g.
20 an hour) then performance won't be that important to you.
However, the BizTalk Mapper isn't really suited where you
have hundreds of links/functoids, or in situations where you need the best
performance possible (e.g. thousands of messages per hour).
If you're not sure if the Mapper will give you the
performance you need, you're better off doing a quick proof-of-concept with a
realistic map and seeing what performance you can get.
Pros:
- Can use it with Receive/Send Ports
- Easiest to start using
Cons:
- Easy to create complex/slow maps
- Difficult to do advanced mapping
- Uses the .NET 1.x XslTransform class
- Standard functoids use inline C# code
Custom XSLT with the BizTalk Mapper
Here we're talking about using the Custom XSL Path
property of a BizTalk Map and specifying an external XSLT file. The contents of
this XSLT file will be compiled into the assembly containing the map.
Note: bear in mind that you can't use <xsl:include>
or <xsl:import>
tags in your external XSLT – the external XSLT file needs to be complete. For
more information on this, see here.
The advantage of external XSLT is that it is very fast –
usually faster than using functoids in a map (depending on the functoids and
the XSLT obviously). In you refer to the speed tests in my previous post,
you'll see that in my tests, external XSLT was 55 time faster than using inline
scripts/default functoids.
If you're au fait with XSLT and your project has the ability
to support external XSLT then this is the best option to use in my mind. If you
use a good external XSLT editor (e.g. Altova's
MapForce) then the issues of maintenance and being able to visualise the
map should disappear.
However, using XSLT can be tricky: because the Mapper uses
XSLT v1.0 you're limited in certain areas (such as string handling, date
handling, and mathematical functions). Additionally, using inherited types can
be tricky if you've never used them before in XSLT.
In these cases, you might be better performing your
transformations in code.
Pros:
- Can use it with Receive/Send Ports
- Transforms are fast
- XSLT is the best choice for XML structures
Cons:
- Need good understanding of XSLT
- Can be difficult to maintain if not using a good XSLT
editor
- Uses the .NET 1.x XslTransform class
External Transform Engine
Because of BizTalk's ability to execute external code from
an orchestration, you can perform transformations via an external engine.
For example you might choose to use the XslCompiledTransform
class to increase the performance or your existing maps, or use an XSLT v2.0
engine such as SAXON.
In both these cases, you could even use your existing BTM
maps if you wanted (by accessing the XSLT from the compiled map class).
Note: When using XslCompiledTransform, using inline C# (or
whatever language) in a map will normally be faster than using an external
assembly i.e. using ExtensionObjects.
The reason for this is that with inline script (i.e. using
the <msxsl:script>
tag) the compiler can generate direct calls to the compiled script assembly
from the transform assembly, whereas with external assemblies, reflection needs
to be used at runtime to invoke a call. See here for more
information on this.
Using an external transformation engine makes sense if you
must use XSLT v2.0 (or are sharing XSLT v2.0 maps with other projects), or if
an external engine gives you a required feature.
However you can only use these engines from an orchestration
(i.e. can't use them with receive/send ports), and any performance related
caching of classes will be up to you to e.g. caching one instance of a compiled
transform for an orchestration's AppDomain.
However you can get substantial performance increases if you
use the right engine and caching strategy.
Plus if your company has an existing maintenance strategy
for a given engine then maintenance of these maps might be a no-brainer.
Pros:
- Transformation can be very fast (if correct engine is
chosen)
- Can share engine/transforms between different technologies
- Can use company-standard transforms if present/required
Cons:
- Can't use it with Receive/Send Ports, only with
Orchestrations
- Can be difficult to maintain if not well understood
- Caching is left up to developer
- Performance is relevant to the skill of the developer and
engine
Transformation in code
By this I mean transformation involving classes and
serialization.
If you've read the previous post (Understanding
the BizTalk Mapper: Part 12 - Performance and Maintainability) then you'll
know that this sort of transformation can be blazingly fast.
However this needs to be taken with a caveat: transformation
in code will only be as good as the programmer writing the code.
If you write C# or VB.NET code which performs badly, then
your transformations will perform badly.
XSLT doesn't suffer from this problem: because the language
is designed to execute rapidly over XML structures: it's more difficult to
write poorly performing XSLT code than C#/VB.NET code.
However, using C#/VB.NET can be a god-send in certain
situations.
One example is where you're using inheritance i.e. base
elements/types in an XSD (if any of the elements/attributes in an XML instance have
an xsi:type
attribute, then you're using inheritance).
In these cases, using source code and inheritance can reduce
the amount of code you need to write as you work with the base class without
worrying about what derived class was actually passed to you.
But remember: don't use C#/VB.NET code to perform transformation
simply because you don't understand XSLT. For a lot of situations it can be
significantly faster to create XSLT code to perform a transformation than the
C#/VB.NET equivalent – and to another XSLT developer it will be easier to
understand and maintain.
Pros:
- Transforms can be fast
- Can be easier to develop/maintain transforms if developer
knows C# better than XSLT
Cons:
- Can't use it with Receive/Send Ports, only with
Orchestrations
- Can be difficult to maintain if not well documented
- Performance is relevant to the skill of the developer
Which one should you use?
Well without knowing your requirements that's a bit like
saying "which airline should I fly with?"
Tell me your requirements, and I'll tell you the best airline!
[the answer's always Virgin
Atlantic or Air New Zealand, by the way... ]
However (in my own biased opinion) I would suggest that a
pure XSLT way is best, followed by the BizTalk Mapper using default functoids,
followed (closely) by doing transformations in code using serializable classes.
If your performance/maintenance requirements are minimal
then it won't really matter.
If you must have the best performance, then use pure
XSLT or transformations in code.
One thing to bear in mind is this: The BizTalk Mapper
creates XSLT.
XSLT is a functional language which uses templates and
pattern matching and as such is very different from a procedural/imperative
language, such as Java, C#, C++, or VB.
It's quite common for non-XSLT programmers to ask how to
create a for/while loop, or how to do an if/case statement in XSLT.
If you're asking those questions, you should to go do a
basic course on XSLT (or read a book) as it works in a very different way.
Properly written XSLT is elegant and fairly simple to
follow.
OK, so that's the end of this series of posts.
I hope it's been useful to you in some way.
I'll gladly welcome any feedback on the series.
Agree or disagree with what I've written? Please let me
know.
Have I made any mistakes, or misrepresented a point of view?
I'll happily make corrections if necessary.
Let me know what you think by leaving comments, or emailing
me at bizbertATprobertsolutions.com (replacing the AT with an @).
Thanks for taking the time to stop by and read.
|