Saturday, September 10, 2005 6:31:10 PM (GMT Standard Time, UTC+00:00)
One of the often overlooked features of BizTalk 2006 (Pathfinder) is that it runs under the .NET 2.0 (whidbey) runtime. This is going to make for some really great performance improvements in Pathfinder - but it also means we (as BizTalk developers) get to work in the coolness that is VS.NET 2005.
One (of the many) really cool VS.NET 2005 features is XSLT debugging. In 2.0, the XslTransform object has been depricated and replaced with the XslCompiledTransform object. This means improved performance (as the XSLT will be compiled into IL and then JIT'ed) and full XSLT debugging built right into VS.NET!
You can approach XSLT debugging in two ways. The first way is just to open an XSLT file in VS.NET and then go to the XML menu (there are command buttons for these commands as well) and select "Debug XSLT". Assuming you are developing maps in BizTalk, you can go the map file in the Solution Explorer right-click and select "Validate Map". When you do this you get an URL (assuming the map is valid) in the output window - which you can do a CTRL+Click on, which will bring the XSLT file generated from the map into the editor window.
The unfortunate thing about this file in the editor is that it is show in the "IE friendly" view, which means you have to right-click on the file and select "View Source" in order to get the source view. At this point you can set a breakpoint in the XSLT.

When you go the XML menu and select "Debug XSLT" - it is going to ask you for an input file. Even if you've selected an input file for the map file in VS.NET, remember this debugger isn't really integrated with BizTalk, it is just a VS.NET feature, so you have to set the input file again for the XSLT debugger. Once you set the input file you can debug, with a full locals and intermediate window! A totally full featured XSLT debugger built right into VS.NET. This rocks.
Another way to use the XSLT debugger is if you have code that uses the XslCompiledTransform object, you can pass true as the optional constructor argument. This is going to create the temporary assemblies the XSLT debugger uses with symbols. This means if you are stepping through C# or VB.NET code in the debugger - you can step right into XSLT!
Now - one thing to note - is that if you are using functoids - this feature is turned off by default in the XslCompiledTransform object, so you have to enable it. Here is a simple exe that takes the name of a BizTalk assembly, a map type compiled inside of it and runs the XSL contained inside of the map with full debugging options on.
static void Main(string[] args)
{
string asm = args[0];//the biztalk assembly
string map = args[1];//the map type
string xslt = args[2];//file name
string input = args[3];//the map input file name
string output = args[4];//the map output file name
//load the assembly
Assembly a = Assembly.LoadFrom(asm);
TransformBase tb = (TransformBase)a.CreateInstance(map);
XslCompiledTransform tform = new XslCompiledTransform(true);
Console.WriteLine("Creating new xslt at {0}", xslt);
FileStream fs = new FileStream(xslt, FileMode.Create);
StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Unicode);
sw.Write(tb.XmlContent);
sw.Flush();
fs.Close();
Console.WriteLine("XSLT {0} created", xslt);
XsltSettings settings = new XsltSettings();
settings.EnableScript = true;
tform.Load(xslt, settings, new XmlUrlResolver());
tform.Transform(input, tb.TransformArgs, new FileStream(output.Length == 0 ? Path.Combine(Path.GetDirectoryName(asm), "ouput.xml") : output, FileMode.Create));
}
So if you ran this code in the debuger, you could open the XSLT file, set a break point or step right into the running XSLT. The other thing that this code does (which the XSLT debugger in VS.NET *doesn't* do ) is add any Extension Objects into the context of the XSLT execution engine. If you are using "linked" functiods (functoids which link to external assemblies instead of internal script, like the Scripting functiod when you choose "external assembly" as the script type) the XSLT debugger built into VS.NET will not add those object for you, this code uses the TransformBase.TransformArgs property to add the XslArgumentList object prepopulated into the running XSLT engine.
Of course, I never want to have to manually do these steps (which would be validting the map, opening the map in source view - and then running this program with different arguments) so I created a VS.NET Add-in to do the job for me. You can download it (full source code) - inside of the zip there is an MSI which you do need to run to get the addin file registered with VS.NET. DebugMapAddIn.zip (611.36 KB)
Once you install the Add-in you will have a new command on the Tools menu in VS.NET - "Debug BizTalk Map". What you have to do is highlight a btm file in your open BizTalk project - also note you have to have setup a input file for the map in the map properties - and then you can run this command - the Add-in will spawn an executable (which is based on the code above) and you can just press F5 to debug after setting a breakpoint in the XSLT (which the Add-in generates and opens in VS.NET automatically). Now - everytime I do this I get a dialog from VS.NET which says "The debugger cannot continue running the process", which you can just press ok on (it doesn't seem to affect the ability of the debugger at all - not sure why it is there - hopefully I can get rid of it somehow). Then you are off debugging the XSLT - with or without extension objects. Hopefully people will find this helpful - it was pretty fun to write.
BizTalk | BizTalk 2006