Extracting BizTalk Messages Content using XPath in Custom Pipeline Components


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.


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.


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)





        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.


Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.