Yossi Dahan [BizTalk]


Monday, August 15, 2005

Calling .net assemblies from custom xslt

It shouldn't have, but it took me a while to figure this one out, so for the small chance I can shorten the process to someone else I've put this here.

If you've read my previous post about custom xslt you know by now that I'm doing more and more custom xlst work rather the standard drag-this-to-there mapping. (you also know that by far I'm not an xslt expert so feel free to comment on this post)

I've been doing this succesfully for a while but then I got to a point that I needed to call a custom .net component I've developed from inside my xslt.
(This is a configuration component, by embedding it in my xsl I can avoid putting static data inside my map that may change in the future - for instance when moving to production)

I've had experience with calling assemblies from a map using the scripting functoid in different ways, but until now did not need to do so from custom xslt.
I found out that the way to do it is exactly the same way you'd do it when calling from a custom xslt script functoid.

First I've created an ExtensionObjects xml from the example in the ExtendingMapper SDK sample - this xml defines the objects that will be called from the xslt - assigning a namesapce to a stongly named assembly and specifying which class should be called.

The sdk samle for this file looks like this:

<ExtensionObject Namespace="http://myScriptorAssembly" AssemblyName="Microsoft.Samples.BizTalk.ExtendingMapper.MapperClassLibrary, Version=, Culture=neutral, PublicKeyToken=f2aaad746c3d94f5" ClassName="Microsoft.Samples.BizTalk.ExtendingMapper.MapperHelper"/>

This xml is saved and then the map's Custom Extension XML property points to it.

To call the xslt I followed closely the exapmle in the ExtendingMapper sdk sample project, there's a map named Scriptor_InlineXsltCallingExternalAssembly.btm that shows how to call an assembly from inside an xslt script functoid, what I found out (which now seems so obvious of course) is that it is exactly the same approach only in my custom xslt rather then in a script functoid.

In my xslt I created a variable and assigned to it the return value of the call to a public method in the class specified in the extension object xml:

<xsl:variable name="v1" xmlns:myScriptPrefix="http://myScriptorAssembly" select="myScriptPrefix:myConcat($param1, $param2)" />

myScriptPrefix is as alias pointing to the same namespace as defined in the extension xml. and then myConcat is a public method in the class configued.

After that poit I can then use <xsl:value-of select="$v1"/> to get the result of the method call.

Very simple indeed, and nothing that is not already in the sdk only that I'm not using any links and functoids on the map but custom xslt file.

I don't know if it possible to call .net assemblies in xslt outside BizTalk but this is a very nice example of how even when you decide to resort to custom xslt to get more flexibility you can still use the great features provided by the BizTalk engine.

Thursday, August 11, 2005

Mapper vs. XSLT

I have what some people may consider a heresy announcment:

I prefer writing custom xslt then using the BizTalk Mapper.

Now, that might not be surprising to some people, but it is definitely surprising me. Especially considering that until two weeks ago I did not have any significat xslt experience.

Of course I know xpath - it comes with the territory - and I know what xslt is, and how it works, but I guess working with BizTalk I simply always defaulted to using the mapper and didn't get to develop my xslt skills. After all - it's visual, It's relativley easy, It's extendible....

Only that its not.

I think when I started with BizTalk, a few years ago now, I was really excited about the mapper, everything seemed so magnificantly simple. You did not need to worry about knowing xslt, xpath, handling namespaces etc.

Then, even when the requirements got more complex (as I gained experience and started seeing the real world of integration out there...) I just added a few more functoids and using the excellent pages feature (that was added in BizTalk 2002) I've split it into pages to make it all clean, nice and more readable...

When things got even more comlex I started calling external assemblies and/or putting in custom xslt bits (which became much easier in BizTalk 2004)

Until one day it hit me - the maps are not really that simple after all (not to mention far from being readable)

So i sat down and shrpened my xslt skill and now, the minute my map stops being a simple link-this-node-to-that-node, I'm moving it all to xslt.

I found out that once I got the hang of it it's quite simple and in my opinion even more readable then a cluttered map with 50 functoids and 17 pages.

Now - Just to make sure nobody get's confused here - I'm still using standard BizTalk map artifacts, which means I'm still doing my transformation as I'd do with a standard map, other then the xslt itself there's no custom code involved, the only difference is that instead of dragging nodes and functoids on the pallete I'm setting the "Custom XSL path" property of my map to an xslt I create in an editor, as shoed here:

Click here for Full size image

Friday, August 05, 2005

Applications in BizTalk 2006

I have to appologize in advance - this is a bit of a moaning post, which is not fair because it's about what is absolutly great new feature in BizTalk, one that we've all longed for since the beginning of time (well, BizTalk time that is) - Applications.

I do think that introducing the concept of applications is great, and I also think Microsoft had actually went much further then I ever expected with the ability to export an MSI for an application.

so all in all - things are great. but....

As someone already mentioned it is a little bit annoying that you cannot associate ports to applications in the BizTalk Explorer inside Visual Studio but only in the BizTalk Administration Console.

this alone is a small problem, maybe just an annoyance but in my opinion - if the developer won't use the applications from the beginning there's a big chance he will not add them later as well, which means there's yet another thing to worry as the development progresses to completion.

To make things worse (again, in my humble opinion), Microsoft did walk that extra mile when it comes to the BizTalk assemblies, and if you looked carefully in the BizTalk Project properties window you've noticed that you can specify the application name.

This property is even set to a free text so you don't have to run to the Admin Console and set up the application up front (not sure if this is done on purpose though).

when you deploy an assembly with the application set, if the application does not exist it gets created and the artifacts in that assembly are automatically associated with the application. however - the next step in the development (and local testing) is to create the ports required to run your newly created orchestration and bind them to the orchestration, and here lies the problem -

because you cannot associate ports with an application the ports you create in the BizTalk Explorer are added to the default application, and then your orchestration cannot be bound to them as it's in a different application altogether....

get my drift?

I sure hope that before the RTM product is released we will be able to associate port to applications in the BizTalk Explorer

Wednesday, August 03, 2005

xpath method gotcha (or I must be missing something...)

In case there's someone out there that still didn't find out about it, there's a magnificent method called xpath you can use in orchestrations.

In any expression type xpath([message],"[xpath expression]") and you get back whatever the xpath expression you've provided points to in your message (a node, a node set, a string).

Very useful when you need to check for values in the message for a decision or a loop, extracting values to use in other places or even extracting bits of a message an assigning them to another (did someone mention message splitting?)

now, I've been doing a bit of all of that this week and must have gotten really tired because in several places I simply forgot to put in the message. So I called the xpath method with a single parameter - the xpath expression.

strangely enough this did not cause any compile time error. Even more strange - it did not even cause a runtime error. It simply returned an empty string.

This one took me a while to figure out (as well as bugging Scott Colestock and Marvin Smith on the newsgroups - thanks guys), but when I did find out how silly I was, right after I hit myself, I started *blessing* BizTalk because unless I'm missing something this is very unexpected behaviour.

BTW - for those of you who are wondering - I've just tried that on BizTalk 2006 and the behaviour is the same.