GD Bloggers

This is the blog site for Microsoft Global Delivery Communities focused in sharing the technical knowledge about devices, apps and cloud.
Follow Us On Twitter! Subscribe To Our Blog! Contact Us

Extracting BizTalk Messages Content using XPath in Custom Pipeline Components

Extracting BizTalk Messages Content using XPath in Custom Pipeline Components

  • Comments 3
  • Likes

Introduction

You find yourself writing custom pipeline components in nearly all BizTalk related projects. So this is a common activity. And usually it will mean eventually you will need to extract data from the message coming on the wire using XPath statements.

Problem

The issues you usually face while trying to extract data from BizTalk massages is that the message stream would not seekable. And another problem is how to do this data extraction with the minimal memory footprint (no XmlDocument L) and also as fast as possible.

Solution

I created mainly two functions that I use commonly for these tasks. The first one is to get the stream from the message and create a seekable one to be used later on.

private Stream GetMessageStream(Microsoft.BizTalk.Message.Interop.IBaseMessage msg, Microsoft.BizTalk.Component.Interop.IPipelineContext context)

{

    Stream stream = msg.BodyPart.GetOriginalDataStream();

 

    if (!stream.CanSeek)

    {

        ReadOnlySeekableStream readStream = new ReadOnlySeekableStream(stream);

 

        if (context != null)

        {

            context.ResourceTracker.AddResource(readStream);

        }

 

        msg.BodyPart.Data = readStream;

        stream = readStream;

    }

    return stream;

}

The second method is the one that would perform the data extraction as follows.

private string ExtractDataValueXPath(Stream MsgStream, string MsgXPath)

{

    XmlReaderSettings settings = new XmlReaderSettings()

    {

        ConformanceLevel = ConformanceLevel.Document,

        IgnoreWhitespace = true,

        ValidationType = ValidationType.None,

        IgnoreProcessingInstructions = true,

        IgnoreComments = true,

        CloseInput = false

    };

    MsgStream.Seek(0, SeekOrigin.Begin);

    XmlReader reader = XmlReader.Create(MsgStream, settings);

    string strValue = null;

    if (!string.IsNullOrEmpty(MsgXPath))

    {

        if (reader.Read())

        {

            XPathDocument xPathDoc = new XPathDocument(reader);

            XPathNavigator xNavigator = xPathDoc.CreateNavigator();

            XPathNodeIterator xNodes = xNavigator.Select(MsgXPath);

            if (xNodes.Count != 0 && xNodes.MoveNext())

            {

                strValue = xNodes.Current.Value;

            }

            MsgStream.Seek(0, SeekOrigin.Begin);

        }

    }

    return strValue;

}

As you can see I am using XPathDocument with a XmlReader to perform this as fast as possible.

 

Comments
  • Thanks you rock!

  • How do you apply the global properties on your extracted message?

  • thank you

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment