locked
Constructing / Updating a message in Loop of BizTalk Orchestration RRS feed

  • Question

  • Hi,

    I have case where i need to to iterate a message received by Orchestration and validate each individual record of that message. Based on result of validation I need to mark a <STATUS> in the same message as Valid or Invalid. Later I need to use this message for filtering Valid records for futher actions.

    Please help on ideas how to achieve it.

    Example / Sample

    --------------------

    Received Message By Orchestartion

    <Items>

    <Item>

    <ID>11</ID>

    <STATUS></STATUS>

    </Item>

    <Item>

    <ID>12</ID>

    <STATUS></STATUS>

    </Item>

    <Item>

    <ID>13</ID>

    <STATUS></STATUS>

    </Item>

    </Items>

    The Item node will be looped and checked for status against ID. This will be done using a method which will receive ID and return STATUS. I need to update back the STATUS in orginal message and then consume following message in the same orchestration.

    Expected Message after LOOP

    --------------------------------

    <Items>

    <Item>

    <ID>11</ID>

    <STATUS>VALID</STATUS>

    </Item>

    <Item>

    <ID>12</ID>

    <STATUS>VALID</STATUS>

    </Item>

    <Item>

    <ID>13</ID>

    <STATUS>INVALID</STATUS>

    </Item>

    </Items>

    Any help will be highly appriciated.


    umair_bs

    Wednesday, December 10, 2014 1:28 PM

Answers

  • You have two options,

    Do it in orchestration, loop through the item(s) node and update the Status field based on your validation logic using XPath

    Or more simple option, pass the message to a .NET helper as below where you can apply your validation logic and update the XML file and .NET helper can return a XMLDocument which you can use in Message-Assignment shape under Construct shape to construct a update message.

    public static XmlDocument ContractUpdateStatusMsg(XmlDocument inXML)
    {
        XmlNodeList items = inXML.SelectNodes("/*[local-name()='Items' and namespace-uri()='']/*[local-name()='Item' and namespace-uri()='']");
    
        foreach (XmlNode item in items)
        {
            //If condition can be contructed based on your validation logic
            //where you send the value of ID to another methods which retrun or false
            if (item.SelectSingleNode("ID").InnerText == "11")
            {
                item.SelectSingleNode("STATUS").InnerText = "VALID";
            }
            else
            {
                item.SelectSingleNode("STATUS").InnerText = "INVALID";
            }
        }
    
        return inXML;
    }


    If this answers your question please mark it accordingly. If this post is helpful, please vote as helpful by clicking the upward arrow mark next to my reply.

    • Marked as answer by Angie Xu Tuesday, December 16, 2014 8:09 AM
    Wednesday, December 10, 2014 3:00 PM

All replies

  • You'd need to create a LOOP, one or two helpers.

    On the received message you will use an XPATH(ReceivedMessage, "count(//*[local-name()='Items']/*[local-name()='Item'])") to get the number of records.

    You will need an XML variable to which you will assign the ReceivedMessage.

    In the Loop (which should start from 1 and run to <= count) you will call the helper. The helper will take 2 parameters (XLANGMessage, int index). This helper is where using the index you will return the status (VALID/INVALID). Then (within the loop) you will have decide shape and see what action needs to be done on the basis of the return value.

    Regards.

    PS: You CANNOT update a Message in BizTalk because of the immutability clause. You will have to necessarily create a NEW message with the modified values. The simplest way to do that is to take the original message into an XMLDocument variable which you update as often as you like. Then in a message construct you assign this XML to a NEW Message.

    • Edited by Shankycheil Wednesday, December 10, 2014 2:41 PM PS
    Wednesday, December 10, 2014 2:38 PM
  • You have two options,

    Do it in orchestration, loop through the item(s) node and update the Status field based on your validation logic using XPath

    Or more simple option, pass the message to a .NET helper as below where you can apply your validation logic and update the XML file and .NET helper can return a XMLDocument which you can use in Message-Assignment shape under Construct shape to construct a update message.

    public static XmlDocument ContractUpdateStatusMsg(XmlDocument inXML)
    {
        XmlNodeList items = inXML.SelectNodes("/*[local-name()='Items' and namespace-uri()='']/*[local-name()='Item' and namespace-uri()='']");
    
        foreach (XmlNode item in items)
        {
            //If condition can be contructed based on your validation logic
            //where you send the value of ID to another methods which retrun or false
            if (item.SelectSingleNode("ID").InnerText == "11")
            {
                item.SelectSingleNode("STATUS").InnerText = "VALID";
            }
            else
            {
                item.SelectSingleNode("STATUS").InnerText = "INVALID";
            }
        }
    
        return inXML;
    }


    If this answers your question please mark it accordingly. If this post is helpful, please vote as helpful by clicking the upward arrow mark next to my reply.

    • Marked as answer by Angie Xu Tuesday, December 16, 2014 8:09 AM
    Wednesday, December 10, 2014 3:00 PM
  • Looping is your incoming message and de batching it inside the loop will solve your issue . 

    Create a variable a type int initialize it with number of incoming record against the xpath something like below .

    VarCount =count(/*[local-name()='Items' and namespace-uri()='']/*[local-name()='Item' and namespace-uri()=''])

    In the loop you can de batch each individual message starting from index of 1 .something like below

    DebatchedMessage = System.String.Format("/*[local-name()='Items' and namespace-uri()='']/*[local-name()='Item' and namespace-uri()=''][] and position()={0}]", varCount);

    Then check the Value for <STATUS> field and based on that create a new message and update it as per your requirement.

    Thanks

    Abhishek

    Wednesday, December 10, 2014 3:11 PM