Great functionality for every BizTalk Developer.(XpathMutatorStream)

By patrickwellink
March 2, 2006
Comments Off on Great functionality for every BizTalk Developer.(XpathMutatorStream)

Ok first of all I have to give lots of credit to Martijn Hogendoorn for helping me with this one. I had a question about how to handle a specific problem within a pipeline.
He said Why don’t you use the XpathMutatorStream for that…..

Well I never heared of the XpathMutatorStream before and after some explanation of Martijn it became clear how it works.
You define a set of Xpath Queries and Program something in the callback. Then you instantiate the XpathMutatorStream and you’re done !.

Once reading of the stream begins your queries will be executed and for every match the callback is executed. And all this is done in a streaming fashion.
Too bad this functionality is only available for bizTalk developers. Equal functionality is available on GotDotNet, it’s called XpathReader

But this one is complete streaming so it works for small messages and very large messages as well.

This can be so usefull if you ever have to develop a pipelinecomponent, I am a littlebit puzzled why Microsoft keeps this stuff hidden.
There is almost no documentation about it on the internet and in the SDK it’s also absent.

For this stuff to work you will need 2 DLL’s. The DLL’s are already in the GAC but you cannot reference them in a project,
so you have to get them somewhere. ( I got them because I installed Martijn’s Management tool for BizTalk 2004).
the DLL’s are  Microsoft.BizTalk.Streaming.dll and Microsoft.BizTalk.XPathReader.dll
( or have a read of this article how to get that dll)

private void DoTheMagic()

 // Set up the Xml Document
 System.Xml.XmlDocument XDOC = new XmlDocument();

 // Set up the stream and rewind
 MemoryStream memstream = new MemoryStream();
 memstream.Position = 0;
 // Define the XpathMutator
 XPathMutatorStream VersionStream =  MatchVersion(memstream);

 // Read the stream and see the magic happen
    XmlTextReader reader = new XmlTextReader(VersionStream);
 while (reader.Read());


private XPathMutatorStream  MatchVersion(MemoryStream OriginalStream)
 // Define the Xpath Collection
 XPathCollection VersionQueries = new XPathCollection();
 VersionQueries.Add(new XPathExpression(FormatXpathQuery(“/Envelope/Header/SomeHeader/SomeIdentification/BerichtNaam/”)));
 VersionQueries.Add(new XPathExpression(FormatXpathQuery(“/Envelope/Header/SomeHeader/SomeIdentification/VersieMajor/”)));
 VersionQueries.Add(new XPathExpression(FormatXpathQuery(“/Envelope/Header/SomeHeader/SomeIdentification/VersieMinor/”)));
 VersionQueries.Add(new XPathExpression(FormatXpathQuery(“/Envelope/Header/SomeHeader/SomeIdentification/Buildnr/”)));

 // Add the Mutator to this Stream
 ValueMutator VersionMatcher = new ValueMutator(this.VersionMatcher);
 XPathMutatorStream VersionStream = new XPathMutatorStream(OriginalStream, VersionQueries, VersionMatcher);
 VersionStream.AfterLastReadEvent +=new AfterLastReadEventHandler(EndOfVersionStreamReached);
 return VersionStream ;

private void VersionMatcher(int matchIdx, XPathExpression matchExpr, string origVal, ref string finalVal)

 System.Diagnostics.Debug.WriteLine(“Xpath :” + matchExpr + ” Value ” + origVal);
 finalVal = origVal;

private void EndOfVersionStreamReached(object src, EventArgs args)
 System.Diagnostics.Debug.WriteLine(“LastRead of VersionStream”);

/// <summary>
/// Reformat an xpath query
/// </summary>
/// <param name=”oldXpath”></param>
/// <returns></returns>
private string FormatXpathQuery(string oldXpath)
 // See if there is anything in there that look like []
 // if so the user probably formatted the string already
 if ( oldXpath.IndexOf(“[“) > 0 )
  return oldXpath;
  // Ok so there is no stuff in there like [local-name()=
  // But we need that for the XpathQuery to work
  // So reformat the query by putting [local-name()= before every node
  // the user wants to select on

  // Define the delimiter
  string delimStr = “/”;
  char [] delimiter = delimStr.ToCharArray();

  // Now split the string
  string[] Split = oldXpath.Split(delimiter);

  // Define the stringbuilder to build the resultstring
  System.Text.StringBuilder Builder = new System.Text.StringBuilder();
  // Enumerate all the strings
  foreach (string s in Split)
   // If Lenght > 0 reformat the xpath query
   if (  s.Length > 0 )
  return Builder.ToString();

Comments: 0

Comments are closed.

  • Recent Posts
  • Recent Comments
  • Archives
  • Categories
  • Meta