Wednesday, December 19, 2007

KB936021 XSLT BizTalk sub map work around

I wrote an article recently regarding the hot fix released by Microsoft regarding locking down MS XML Core Services (version 3,4,6) to set the resolveExternals property to false by default. Previously this was true. If you haven't read this article, you can here.

Of course this is a simple fix if you are still developing native apps using the MS XML Core Service libraries. Simply set resolveExternals to true before doing a XSLT translation.

This fix unfortunately a little more difficult if you have written you're own maps in any version of BizTalk using XSLT as you have no control over the MS XML Core Services library.

We have written a tool that converts all toplevel maps and imports the sub maps, namespaces, keys, JavaScript and VBScript from any sub map references. The tool does a recusive call as it is possible to have sub maps within sub maps. It is recomended to add the imported namespaces to the exclude-result-prefixes attribute in the top level document as depending on whether there is existing code that reads the output XML with XPath for example, this will prevent that code from breaking.

I'd love to post the source code for the tool here, but it belongs to our client so sadly I can't. It is a relatively simple process using the .NET DOM. As we are using MS XML 3 (in BizTalk 2002) to do the translation, we used MS XML 3 COM object to do a validation after the conversion had taken place. Bear this is mind!

2 comments:

govis said...

Simon, It's interesting you mentioned sub maps in your post. I have been looking for some information on how to create submaps to perform common transformation and call them from other maps. Just like subroutines in a traditional programming are used to facilitate reuse as opposed to copy and paste. Do you happen know if this is doable and if so, do you have something that might be of help?

Thanks,

Viktor

Simon Hart said...

Viktor,

This is supported in XSLT.

You use the import keyword in your toplevel file such as:

xsl:import href="file://C:\mysub.xsl"

You then then call templates within that map by using the call-template keyword:

xsl:call-template name="mytemplate"
xsl:with-param name="message" select="Body/Message"
xsl:call-template

You can pass parameters using the with-param keyword as shown above.

Note: I had to loose the <> as blogger cannot process this comment.