Connected Thoughts – Thiago Almeida

May 31, 2008

Updating repeating nodes in an XML Document with the same value using XPathMutatorStream

Filed under: BizTalk — Tags: , , , , , — Thiago Almeida @ 10:35 pm

 It’s been a while since I’ve posted some BizTalk coding tidbit… Busy times!

 I often have to set the value of an element under a message’s repeating node with the same value. Of course, normally you’d use a map, but what if the value isn’t in the source message? The last time I ran into this was in a project where orders coming into BizTalk via a web service had to be inserted into an AS400 system. The way the already existing AS400 tables were designed to link the order header and the order details was to have the same GUID inserted into both tables, so the order items schema had a GUID field for each line of the order.

 I couldn’t use a distinguished field to set the value of the GUID in the order lines schema. This is, of course, because it’s under a repeating node. Even if you have a second message with the the value (say, for example, you use the SQL Adapter and a stored procedure to insert the order header and it returns the newly generated ID in a message), you would then have to use a map with multiple inputs… So it ocurred to me that this could be a great opportunity for the XPathMutatorStream class! This class is usually used in custom pipeline components. It has been blogged about by Martijn Hoogendoorn and Patrick Wellink amongst others and I wanted to share how I used it. Say we have the following schemas and map:

XPathMutatorStream Map

And we make sure the WEBGUID element on the destination schema is populated with a blank value by selecting it and setting its “Value” property to <empty> (this will create the element with an empty value on the destination message):

 Then, I created the following helper c# class library to perform the update. Don’t forget to reference Microsoft.Biztalk.Streaming and Microsoft.BizTalk.XPathReader (get them from the GAC). 

using System;

using System.Xml;

using System.IO;

using Microsoft.BizTalk.XPath;

using Microsoft.BizTalk.Streaming;

 

namespace MyCompanyUtilities

{

    [Serializable]

    public class XPathUtil

    {

 

        private string newValue = “”;

  

        public string NewValue

        {

            get { return newValue; }

            set { newValue = value; }

        }

 

        private string xpathToUpdate = “”;

 

        public string XpathToUpdate

        {

            get { return xpathToUpdate; }

            set { xpathToUpdate = value; }

        }

 

        //Updates an xml document with all matches in an xpath with a value

        public XmlDocument updateWithXpath(XmlDocument xDoc)

        {

            //Check for valid arguments

            if (newValue == “”)

                throw new ArgumentException(“NewValue”);

            if (xpathToUpdate == “”)

                throw new ArgumentException(“XpathToUpdate”);

 

            XmlDocument retXml = new XmlDocument();

 

            //Setup the stream and rewind

            using (MemoryStream memstream = new MemoryStream())

            {

                //Copy xml document to memory stream and rewind

                xDoc.Save(memstream);

                memstream.Position = 0;

 

                //Define the XPathMutator

                XPathCollection queries = new XPathCollection();

                queries.Add(new XPathExpression(xpathToUpdate));

                ValueMutator xpathMatcher = new ValueMutator(this.XPathCallBack);

 

                //Get resulting stream into response xml

                retXml.Load(new XPathMutatorStream(memstream, queries, xpathMatcher));

            }

 

            return retXml;

        }

 

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

        {

            finalVal = newValue;

        }

    }

}

 So from there it was just a case of referencing the c# class library from my BizTalk solution, and calling the helper class from the orchestration in a construct shape (in the same construction shape as the map). Here’s how the sample orchestration looks like:

XPathMutatorStream Orchestration

  I created a variable in the orchestration for the class above. The “Set GUID” construct shape has the following: 

xpathHelper = new MyCompanyUtilities.XPathUtil();

xpathHelper.XpathToUpdate = “/*[local-name()='Root' and namespace-uri()='http://MyCompany.OrderItems']/*[local-name()='TBWEBITEM' and namespace-uri()='']/*[local-name()='WEBGUID' and namespace-uri()='']“;

xpathHelper.NewValue = msg_WebOrder(BTS.MessageID);

msg_OrderItems = xpathHelper.updateWithXpath(msg_OrderItems);

  So when I input the following message: 

<ns0:Root xmlns:ns0=http://MyCompany.WebOrder>

  <WebOrder>

    <OrderHeader>

      <OrderNumber>1</OrderNumber>

    </OrderHeader>

    <Items>

      <Item>

        <ItemNumber>23</ItemNumber>

        <ItemDescription>Cheese</ItemDescription>

        <Quantity>10</Quantity>

        <UnitPriceExcTax>5.4</UnitPriceExcTax>

      </Item>

      <Item>

        <ItemNumber>14</ItemNumber>

        <ItemDescription>Ham</ItemDescription>

        <Quantity>10</Quantity>

        <UnitPriceExcTax>4.0</UnitPriceExcTax>

      </Item>

      <Item>

        <ItemNumber>12</ItemNumber>

        <ItemDescription>Bread</ItemDescription>

        <Quantity>1</Quantity>

        <UnitPriceExcTax>3.30</UnitPriceExcTax>

      </Item>

    </Items>

  </WebOrder>

</ns0:Root>

 The output message is: 

<ns0:Root xmlns:ns0=http://MyCompany.OrderItems>

  <TBWEBITEM>

    <WEBGUID>d181486e-649b-4d29-87ab-a811bb175ef3</WEBGUID>

    <WEBITMNBR>23</WEBITMNBR>

    <WEBITMDSC>Cheese</WEBITMDSC>

    <WEBQTY>10</WEBQTY>

    <WEBPRC>5.4</WEBPRC>

  </TBWEBITEM>

  <TBWEBITEM>

    <WEBGUID>d181486e-649b-4d29-87ab-a811bb175ef3</WEBGUID>

    <WEBITMNBR>14</WEBITMNBR>

    <WEBITMDSC>Ham</WEBITMDSC>

    <WEBQTY>10</WEBQTY>

    <WEBPRC>4.0</WEBPRC>

  </TBWEBITEM>

  <TBWEBITEM>

    <WEBGUID>d181486e-649b-4d29-87ab-a811bb175ef3</WEBGUID>

    <WEBITMNBR>12</WEBITMNBR>

    <WEBITMDSC>Bread</WEBITMDSC>

    <WEBQTY>1</WEBQTY>

    <WEBPRC>3.30</WEBPRC>

  </TBWEBITEM>

</ns0:Root>

 So the helper class updated all the WEBGUID elements with the same value without us having to use a map with multiple inputs, or performing a loop inside the orchestration, or browsing through the message using XpathNavigator. Of course you can use the XPathMutatorStream with any repeating node you want or with a list of different xpath queries that will match somewhere in the message. You can also add some funky logic in the XPathCallBack method to have it use different values depending on the original value.

Dowload the sample here.

Note: I could have also used a custom pipeline functoid to get the Message ID from the source schema by using the “Custom GetContextProperty functoid“.

May 24, 2008

ACSUG meeting with Ron Jacobs

Filed under: WCF — Tags: , , , , , , , , , , , — Thiago Almeida @ 4:55 pm

Ron Jacobs is a legend. He spent a little less than a week over here in New Zealand and presented at four meetings or more every day. When it came to closing it with a golden key :) by presenting at the inaugural Auckland Connected Systems User Group meeting he was as active and enthusiastic as ever. As he pointed out the “V” energy drink also helped! And all this was after doing a similar tour around Australia.

His talk was on creating and consuming RESTful Web Services with WCF. As a lot of you know REST is an emerging architecture for exposing services over the Web that takes advantage of the features of the original HTTP protocol like caching, stateless services and easy requests (even notepad can call them). It is perfect for high user load and is being used by big names like Flickr, Yahoo, Google amongst others. I will be posting a few of my notes in my next post.

Thanks to all that attended, the meeting was a success (and congratulations to those that won the two games drawn at the end of the meeting!). The meeting slides can be found on the meeting page under attachments, and the sample code are on Ron’s blog. We will upload some pictures taken during the meeting in the coming week and put them on the photo galleries page of the user group website.

I’d like to thank Darryl Burling for noticing that the user group and Ron’s dates coincided and making it happen, and Mark Carroll for hosting Ron while he was over in New Zealand and helping me with setting up the meeting.

If you are in Auckland this coming week make sure you come to the Ellerslie .NET User Group meeting on Wednesday 28 May to see Alex Henderson present on the REST in .NET topic. It will be valuable for those that came to the ACSUG meeting to really understand the subject and an opportunity to learn it for those that couldn’t make it to Ron’s talk. Don’t forget to register by following the link on the user group website.

May 16, 2008

BizTalk WCF Adapter Pack Articles on TopXML.com

Filed under: BizTalk, WCF — Tags: , , , — Thiago Almeida @ 10:06 am

 Richard Seroter has finished writing his articles on TopXML.com about BizTalk and WCF. He goes into a lot of detail on all that can be done with the WCF adapters in BizTalk and also the WCF Adapter Pack for Line of Business Applications. If you work with BizTalk and are interested in WCF the articles are a *must read*. His post “Article Series on BizTalk and WCF: Part IX, BizTalk Adapter Pack BizTalk Patterns” has the links to each article.

May 12, 2008

Auckland Connected Systems User Group – Creating and Consuming RESTful Web Services with WCF – Ron Jacobs

Filed under: BizTalk — Tags: , , , , , , , , , — Thiago Almeida @ 1:51 pm

 

Auckland Connected Systems Logo

 It is my pleasure to to introduce you to the Auckland Connected Systems User Group. This is a new .NET User Group in Auckland, New Zealand. The meetings will be held at Datacom and at Microsoft (our sponsors), we try to meet once every two months unless we have an impromptu speaker. The technologies covered will be around BizTalk, WCF, WF and any other integration technologies from Microsoft.

  If you are interested please check out the website and subscribe to the newsletter or subscribe to the News RSS feed to learn about upcoming meetings. You can also join the user group as we might add sponsor offers and member downloads in the future after meetings.

  To kick it off in a big way our first meeting details are below:

  Event: Creating and Consuming RESTful Web Services with WCF – Ron Jacobs

  Description: RESTful Web services are emerging as a new way to make your web service available to even the simplest of client apps. Learn how to design, build, create and consume these services with WCF.

  About Ron Jacobs:
  Ron Jacobs is a Sr. Technical Evangelist in the Microsoft Platform Evangelism group based at the company headquarters in Redmond Washington. Ron’s evangelism is focused on Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF). He is also the former host of the ARCast series on Channel 9 about IT Architecture.

  Date:
 Frida, 23 of May 2008 5:30 p.m.

  Location:  

 MPC Room
 Microsoft New Zealand
 Level 5, 22 Viaduct Harbour Avenue
 Auckland, New Zealand 1010

 Please register for the meeting by filling out your details on the meeting page.

May 9, 2008

BizTalk Server R3 trickle feed

Filed under: BizTalk — Tags: — Thiago Almeida @ 10:19 am

Isn’t it fun how Microsoft trickle feeds us BizTalk information hungry souls with details about BizTalk Server R3? It is already in a TAP program so surely they know a lot about it…

Like Nick Heppleston’s “BizTalk to Incorporate Covast B2B Capabilities” post I am also concerned about them acquiring Covast’s B2B capabilities. It is on one side quite exciting because Covast will add support to industry specific standards (Retail, Manufacturing, etc) and new adapters, but it will certainly get everyone thinking: what? Didn’t Microsoft just introduce their own EDI and AS2 adapters and tools? Hopefully they’ll be able to merge the two, as improbable as this may sound.

Another one is UDDI and SOA patterns and practices. This is the direction the ESB Guidance was going, so it’s nice to see it incorporated into a BizTalk release. But we can only wonder for now.

At any rate, because Oslo is still far away, it is without a doubt a required release to support the 2008 gang: Windows Server 2008, SQL Server 2008, Visual Studio 2008. Maybe it should have been called BizTalk Server 2008. And of course, as Steven Martin himself says, they might as well introduce all of the additional capabilities they have available at the moment.

Blog at WordPress.com.