In few cases we don't have to actually create a map for transforming the message and this custom pipeline component used to transform an XML message using XSLT.
Sample for suppress the blank nodes before message going to final destination.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="@*|node()"><xsl:if test=". != ''"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:if></xsl:template></xsl:stylesheet>
Pipeline component:
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
[System.Runtime.InteropServices.Guid("34b2fdfe-0c6f-4e6a-992a-511058a2c467")]
[ComponentCategory(CategoryTypes.CATID_Encoder)]
public class TransformMessage : IBaseComponent, Microsoft.BizTalk.Component.Interop.IComponent, IComponentUI, IPersistPropertyBag
{
#region Private Variables
private ResourceManager resourceManager = null;
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="Class1"/> class.
/// </summary>
public TransformMessage()
{
resourceManager = new ResourceManager("My.Common.BizTalk.PipelineComponent.XSLTtransform.TransformMessage", Assembly.GetExecutingAssembly());
}
#endregion
#region Public properties
/// <summary>
/// Gets or sets the custom XSLT.
/// </summary>
/// <value>
/// The custom XSLT.
/// </value>
[DisplayName("CustomXSLT")]
public string CustomXSLT
{
get;
set;
}
#endregion
#region IBaseComponent
/// <summary>
/// Description of the Component
/// </summary>
public string Description
{
get { return resourceManager.GetString("COMPONENTDESCRIPTION", CultureInfo.InvariantCulture); }
}
/// <summary>
/// Name of the Component
/// </summary>
public string Name
{
get { return resourceManager.GetString("COMPONENTNAME", CultureInfo.InvariantCulture); }
}
/// <summary>
/// Version of the Component
/// </summary>
public string Version
{
get { return resourceManager.GetString("COMPONENTVERSION", CultureInfo.InvariantCulture); }
}
#endregion
#region IPersistPropertyBag
/// <summary>
/// GetClassID of component for usage from unmanaged code.
/// </summary>
/// <param name="classID"></param>
public void GetClassID(out Guid classID)
{
classID = new Guid("00b3e605-1cbe-41ff-bb43-4bad07f2f3ef");
}
/// <summary>
/// InitNew
/// </summary>
public void InitNew()
{
}
/// <summary>
/// Loads configuration properties for the component
/// </summary>
/// <param name="propertyBag"></param>
/// <param name="errorLog"></param>
public void Load(IPropertyBag propertyBag, int errorLog)
{
try
{
CustomXSLT = ReadPropertyBag<string>(propertyBag, "CustomXSLT");
}
catch (NullReferenceException ex)
{
System.Diagnostics.EventLog.WriteEntry("Error in reading property bag", ex.Message);
throw ex;
}
}
/// <summary>
/// Saves the current component configuration into the property bag
/// </summary>
/// <param name="pb">Configuration property bag</param>
/// <param name="fClearDirty">not used</param>
/// <param name="fSaveAllProperties">not used</param>
public virtual void Save(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, bool fClearDirty, bool fSaveAllProperties)
{
WritePropertyBag(pb, "CustomXSLT", this.CustomXSLT);
}
#endregion
#region IComponentUI
/// <summary>
/// Component icon to use in BizTalk Editor
/// </summary>
[System.ComponentModel.Browsable(false)]
public IntPtr Icon
{
get
{
return ((System.Drawing.Bitmap)(this.resourceManager.GetObject("COMPONENTICON", System.Globalization.CultureInfo.InvariantCulture))).GetHicon();
}
}
/// <summary>
/// The Validate method is called by the BizTalk Editor during the build of a BizTalk project.
/// </summary>
/// <param name="projectSystem"></param>
/// <returns></returns>
public System.Collections.IEnumerator Validate(object projectSystem)
{
return null;
}
#endregion
#region IComponent
/// <summary>
/// Execute Method
/// </summary>
/// <param name="pContext"></param>
/// <param name="pInMsg"></param>
/// <returns></returns>
public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
{
Stream vStream = new VirtualStream(pInMsg.BodyPart.GetOriginalDataStream());
ReadOnlySeekableStream message = new ReadOnlySeekableStream(vStream);
MemoryStream memoryStream = new MemoryStream();
message.CopyTo(memoryStream);
message.Position = 0;
XPathDocument xPathDoc = new XPathDocument(message);
XslCompiledTransform transform = new XslCompiledTransform();
MemoryStream xslStream = new MemoryStream();
byte[] outBytes = System.Text.Encoding.ASCII.GetBytes(CustomXSLT);
xslStream.Write(outBytes, 0, outBytes.Length);
xslStream.Position = 0;
XPathDocument xsltDoc = new XPathDocument((Stream)xslStream);
transform.Load(xsltDoc);
//transform.Load(
memoryStream = new MemoryStream();
transform.Transform(xPathDoc, null, memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
pInMsg.BodyPart.Data = memoryStream;
return pInMsg;
}
#endregion
#region Private Methods
/// <summary>
/// Reads the property bag.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="propertyBag">The property bag.</param>
/// <param name="propName">Name of the property.</param>
/// <returns></returns>
private T ReadPropertyBag<T>(IPropertyBag propertyBag, string propName)
{
T returnValue = default(T);
object val = null;
try
{
propertyBag.Read(propName, out val, 0);
returnValue = (T)Convert.ChangeType(val, typeof(T));
}
catch (System.ArgumentException)
{
return returnValue;
}
catch (System.Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("XMLDebatch", string.Concat("Error in reading into property bag", ex.Message));
throw new ApplicationException(string.Concat("Error in reading into property bag: ", ex.Message));
}
return returnValue;
}
/// <summary>
/// Writes the property bag.
/// </summary>
/// <param name="propertyBag">The property bag.</param>
/// <param name="propName">Name of the property.</param>
/// <param name="val">The value.</param>
private void WritePropertyBag(IPropertyBag propertyBag, string propName, object val)
{
try
{
propertyBag.Write(propName, ref val);
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("Error in writing into property bag", ex.Message);
throw new ApplicationException(string.Concat("Error in writing into property bag: ", ex.Message));
}
}
#endregion
}
Sample for suppress the blank nodes before message going to final destination.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="@*|node()"><xsl:if test=". != ''"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:if></xsl:template></xsl:stylesheet>
Pipeline component:
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
[System.Runtime.InteropServices.Guid("34b2fdfe-0c6f-4e6a-992a-511058a2c467")]
[ComponentCategory(CategoryTypes.CATID_Encoder)]
public class TransformMessage : IBaseComponent, Microsoft.BizTalk.Component.Interop.IComponent, IComponentUI, IPersistPropertyBag
{
#region Private Variables
private ResourceManager resourceManager = null;
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="Class1"/> class.
/// </summary>
public TransformMessage()
{
resourceManager = new ResourceManager("My.Common.BizTalk.PipelineComponent.XSLTtransform.TransformMessage", Assembly.GetExecutingAssembly());
}
#endregion
#region Public properties
/// <summary>
/// Gets or sets the custom XSLT.
/// </summary>
/// <value>
/// The custom XSLT.
/// </value>
[DisplayName("CustomXSLT")]
public string CustomXSLT
{
get;
set;
}
#endregion
#region IBaseComponent
/// <summary>
/// Description of the Component
/// </summary>
public string Description
{
get { return resourceManager.GetString("COMPONENTDESCRIPTION", CultureInfo.InvariantCulture); }
}
/// <summary>
/// Name of the Component
/// </summary>
public string Name
{
get { return resourceManager.GetString("COMPONENTNAME", CultureInfo.InvariantCulture); }
}
/// <summary>
/// Version of the Component
/// </summary>
public string Version
{
get { return resourceManager.GetString("COMPONENTVERSION", CultureInfo.InvariantCulture); }
}
#endregion
#region IPersistPropertyBag
/// <summary>
/// GetClassID of component for usage from unmanaged code.
/// </summary>
/// <param name="classID"></param>
public void GetClassID(out Guid classID)
{
classID = new Guid("00b3e605-1cbe-41ff-bb43-4bad07f2f3ef");
}
/// <summary>
/// InitNew
/// </summary>
public void InitNew()
{
}
/// <summary>
/// Loads configuration properties for the component
/// </summary>
/// <param name="propertyBag"></param>
/// <param name="errorLog"></param>
public void Load(IPropertyBag propertyBag, int errorLog)
{
try
{
CustomXSLT = ReadPropertyBag<string>(propertyBag, "CustomXSLT");
}
catch (NullReferenceException ex)
{
System.Diagnostics.EventLog.WriteEntry("Error in reading property bag", ex.Message);
throw ex;
}
}
/// <summary>
/// Saves the current component configuration into the property bag
/// </summary>
/// <param name="pb">Configuration property bag</param>
/// <param name="fClearDirty">not used</param>
/// <param name="fSaveAllProperties">not used</param>
public virtual void Save(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, bool fClearDirty, bool fSaveAllProperties)
{
WritePropertyBag(pb, "CustomXSLT", this.CustomXSLT);
}
#endregion
#region IComponentUI
/// <summary>
/// Component icon to use in BizTalk Editor
/// </summary>
[System.ComponentModel.Browsable(false)]
public IntPtr Icon
{
get
{
return ((System.Drawing.Bitmap)(this.resourceManager.GetObject("COMPONENTICON", System.Globalization.CultureInfo.InvariantCulture))).GetHicon();
}
}
/// <summary>
/// The Validate method is called by the BizTalk Editor during the build of a BizTalk project.
/// </summary>
/// <param name="projectSystem"></param>
/// <returns></returns>
public System.Collections.IEnumerator Validate(object projectSystem)
{
return null;
}
#endregion
#region IComponent
/// <summary>
/// Execute Method
/// </summary>
/// <param name="pContext"></param>
/// <param name="pInMsg"></param>
/// <returns></returns>
public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
{
Stream vStream = new VirtualStream(pInMsg.BodyPart.GetOriginalDataStream());
ReadOnlySeekableStream message = new ReadOnlySeekableStream(vStream);
MemoryStream memoryStream = new MemoryStream();
message.CopyTo(memoryStream);
message.Position = 0;
XPathDocument xPathDoc = new XPathDocument(message);
XslCompiledTransform transform = new XslCompiledTransform();
MemoryStream xslStream = new MemoryStream();
byte[] outBytes = System.Text.Encoding.ASCII.GetBytes(CustomXSLT);
xslStream.Write(outBytes, 0, outBytes.Length);
xslStream.Position = 0;
XPathDocument xsltDoc = new XPathDocument((Stream)xslStream);
transform.Load(xsltDoc);
//transform.Load(
memoryStream = new MemoryStream();
transform.Transform(xPathDoc, null, memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
pInMsg.BodyPart.Data = memoryStream;
return pInMsg;
}
#endregion
#region Private Methods
/// <summary>
/// Reads the property bag.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="propertyBag">The property bag.</param>
/// <param name="propName">Name of the property.</param>
/// <returns></returns>
private T ReadPropertyBag<T>(IPropertyBag propertyBag, string propName)
{
T returnValue = default(T);
object val = null;
try
{
propertyBag.Read(propName, out val, 0);
returnValue = (T)Convert.ChangeType(val, typeof(T));
}
catch (System.ArgumentException)
{
return returnValue;
}
catch (System.Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("XMLDebatch", string.Concat("Error in reading into property bag", ex.Message));
throw new ApplicationException(string.Concat("Error in reading into property bag: ", ex.Message));
}
return returnValue;
}
/// <summary>
/// Writes the property bag.
/// </summary>
/// <param name="propertyBag">The property bag.</param>
/// <param name="propName">Name of the property.</param>
/// <param name="val">The value.</param>
private void WritePropertyBag(IPropertyBag propertyBag, string propName, object val)
{
try
{
propertyBag.Write(propName, ref val);
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("Error in writing into property bag", ex.Message);
throw new ApplicationException(string.Concat("Error in writing into property bag: ", ex.Message));
}
}
#endregion
}
No comments:
Post a Comment