Every wonder how you could possibly reuse the XSLT that we store in BizTalk maps? Every wonder how you could pick and chose which map to execute in your code from the compiled BizTalk Assembly. Well there is a way! The type containing the map xslt is devired from TransformBase contained in Microsoft.XLANGs.BaseTypes. We can use that object to extract the xslTransform and the xslArgumentList objects from the BizTalk Map Type residing in the assembly and pass them to TransformMessage. Pretty cool. This allows you to resuse BizTalk maps and call them dynamically as you see fit. For example, imagine the case of dynamic send ports where you also need to determine the map execution model dynamically or through a set of rules. Remember though, this is completely Unsupported by Microsoft.
I put together a simple project from the shipped EAISolutions tutorial. I added the EAIUtilies project to it which has the code for this. This code is then called within a message assignment shape within the EAIOrchestration project to create a new message from the executed map. Thanks Ashwani for helping me troubleshoot.
Download the project ..Check it out..
sing System;
using System.Xml;
using System.Xml.Xsl;
using Microsoft.XLANGs.BaseTypes;
using System.Reflection;
using System.IO;
using System.Text;
using System.Xml.XPath;
namespace EAI.Utilities
{
/// <summary>
/// Summary description for Class1.
/// </summary>
[Serializable()]
public class MapHelper
{
public MapHelper()
{
}
public static XmlDocument GetMappedDoc(Microsoft.XLANGs.BaseTypes.XLANGMessage msg)
{
XmlDocument xmlDocOutputMsg = new XmlDocument();
XmlDocument xmlDocInputMsg = null;
try
{
xmlDocInputMsg = (XmlDocument)msg[0].RetrieveAs(typeof(XmlDocument));
Assembly mapAssembly = Assembly.LoadWithPartialName(“EAISchemas”);
Type mapTypeClass = mapAssembly.GetType(“EAISchemas.MapToReqDenied”);
TransformBase map = (TransformBase)System.Activator.CreateInstance(mapTypeClass);
XslTransform transform = map.Transform;
XsltArgumentList argList = map.TransformArgs;
xmlDocOutputMsg = TransformMessage(transform,argList,xmlDocInputMsg);
}
catch (Exception exc)
{
System.Diagnostics.EventLog.WriteEntry(“mapHelper”,exc.InnerException.ToString());
}
return xmlDocOutputMsg;
}
private static XmlDocument TransformMessage(XslTransform xslt,XsltArgumentList args,XmlDocument sourceDoc)
{
XmlNodeReader sourceRoot=new XmlNodeReader(sourceDoc);
XPathDocument srcXPath=new XPathDocument(sourceRoot);
MemoryStream stm = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(stm,System.Text.Encoding.Unicode);
xslt.Transform(srcXPath,args,writer,null);
stm.Flush();
stm.Seek(0,SeekOrigin.Begin);
XmlTextReader destReader;
XmlDocument destDoc;
try
{
destReader= new XmlTextReader(stm);
destDoc = new XmlDocument();
destDoc.Load(destReader);
return destDoc;
}
finally
{
}
}
}
}