Counting nodes with the BizTalk mapper and custom XSLT

March 27, 2006 / Comments Off on Counting nodes with the BizTalk mapper and custom XSLT

Ok here is something quite simple, but when I Googled for it i could not find anu solution to this problem. Here is the case. I have a docuemnt that looks like this….

<SomeRoot>
  <Header>
    <NumberOfChildren>??</NumberOfChildren>
    <Child>
      <SomeData>Data A</SomeData>
    </Child>
    <Child>
      <SomeData>Data B</SomeData>
    </Child>
  </Header>
  <Header>
    <NumberOfChildren>??</NumberOfChildren>
    <Child>
      <SomeData>Data B</SomeData>
    </Child>
  </Header>
</SomeRoot>

If I would use the BizTalk COUNT functoid it would give me :

<SomeRoot>
  <Header>
    <NumberOfChildren>3</NumberOfChildren>
    <Child>
      <SomeData>Data A</SomeData>
    </Child>
    <Child>
      <SomeData>Data B</SomeData>
    </Child>
  </Header>
  <Header>
    <NumberOfChildren>3</NumberOfChildren>
    <Child>
      <SomeData>Data B</SomeData>
    </Child>
  </Header>
</SomeRoot>

i.e.  BizTalk is always counting the nodes from the root of the document. I needed to know the number childeren within each recurring node. It turned out that i had to use some small XSLT.
I used the iteration functoid to give an indication of the current node I was in. I needed to capture this as a variable in my XSLT. Here is what the map looks like.

 

The Scripting functoid looks like this (I use an Inline XSLT template)

The complete XSLT looks like this (there is one line missing in this screenshot)

<xsl:template name="MyXsltCountTemplate">
<xsl:param name="Iteration" />

<xsl:for-each select="/SomeRoot/Header">
   <xsl:if test="position()=$Iteration">
      <xsl:element name="NumberOfChildren">
      <xsl:value-of select="count(./Child)" />
     </xsl:element>
   </xsl:if> 
</xsl:for-each>
</xsl:template>

And with this little script I get what I want the result of a map would give me the desired results.

<SomeRoot>
  
<Header>
      <
NumberOfChildren>2</NumberOfChildren>
      <
Child>
         
<SomeData>Data A</SomeData>
      </Child>
     
<Child>
        
<SomeData>Data B</SomeData>
     
</Child>
   </
Header>
   <
Header>
      <
NumberOfChildren>1</NumberOfChildren>
      <
Child>
        
<SomeData>Data B</SomeData>
     
</Child>
   </
Header>
</
SomeRoot>

 

 

 

 

This will end all Disk IO related performance problems

March 20, 2006 / Comments Off on This will end all Disk IO related performance problems

Imagine having this as storage…
I guess it will speed up your SQL queries a bit. I even think running BizTalk on it will improve performance a little bit…..
Some specs…

Tera-RamSan highlights:

  • Up to 1 Terabyte of non-volatile DDRRAM in 24U.

  • Unlimited overall capacity

  • Over 3.2 million random I/O requests per second.

  • Over 24 GB/second of random sustainable data bandwidth.

  • Up to 512 physical LUNs.

  • Requires 2,500 watts of power.

  • Up to 8 independent non-volatile solid state disks (SSD) modules. Each SSD module is a RamSan-400, including 128 GB of DDRRAM and up to eight 4-Gbit Fibre Channel connections.

This will make you and everybody laugh (if you are dutch)

I know this is not really business like but this is just too funny….(turn your speaker on !!!)

just go >here< (come on click it)  and type your name, select the "Jordaan" version and you will laugh GUARANTEED
Your colleagues will look up and probably laugh also… if they don’t they have a lack of humor.

I know they are ringtones, I just tell you to listen to them. I am not telling you to order them….

 

Great functionality for every BizTalk Developer.(XpathMutatorStream)

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();
 XDOC.Load(@”D:DevelopmentXpathMutatorsampleXML.xml”);


 // Set up the stream and rewind
 MemoryStream memstream = new MemoryStream();
 XDOC.Save(memstream);
 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;
 }
 else
 {
  // 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 )
   {
    Builder.Append(“/*[local-name()='”);
    Builder.Append(s);
    Builder.Append(“‘]”);
   }
  }
  return Builder.ToString();
 }
}

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