Often you will want to count specific nodes present in messages to be able to add some business logic inside your Orchestrations. Like almost everything in life, there are several ways to accomplish this, for example:
- Using XPath
- Using C# code
In this blog, we explain the XPath approach to count nodes.
Working with XPath inside Orchestrations is a powerful and straightforward feature that is available since BizTalk Server 2004, and it doesn’t require any additional effort like the alternative (C# Code). Xpath is also a lovely way to retrieve values from BizTalk Server messages, especially when you can not use Distinguished Fields and Property Fields, such as looping records, or when you don’t want to use property promotions.
BizTalk XPath can be used to both read values and set values inside your Message. Of course, to set values in your message, you need to be inside a Message Construct shape. You can learn more about this topic on my blog post: BizTalk Training – Accessing and change message values inside an orchestration.
However, if you are not quite familiar with XPath, it can be a complicated task to understand, at least in the beginning, how to retrieve a specific value or, in this case, how to count the number of nodes present on the message.
To count the number of nodes present in a message you need to use the following template expression:
<variable_name> = System.Convert.ToInt32(xpath(<message_name>,”count(<xpath_query>)”));
Despite the template expression be the same, you will find several approaches to count the nodes.
Using XPath count() function: approach 1
The easy way is to take advantage of the Instance XPath property that is present in the Schema Editor.
You can simply copy that value and replace the <xpath_query> with that value:
varCount = System.Convert.ToInt32(xpath(msgInput,”count(//*[local-name()=’XMLSample’ and namespace-uri()=’http://POC.BizTalk.CountXMLNodesInsideOrchestrations.XMLSample’]/*[local-name()=’Object’ and namespace-uri()=”])”));
The only difference is instead of starting with /* it should start with //*.
The only disadvantage of using this approach is that if you have several namespaces and complex XML structures, the XPath query will become large and difficult to read.
Using XPath count() function: approach 2
The second approach is using the same strategy of approach 1, but instead of using the full Instance XPath property value, we will go clean up a bit by removing the namespace-uri property from the XPath query:
varCount = System.Convert.ToInt32(xpath(msgInput,”count(//*[local-name()=’XMLSample’]/*[local-name()=’Object’])”));
Obviously, the expression becomes simpler to read, but this approach requires an initial extra work of cleaning up the expression.
Using XPath count() function: using filters
However, sometimes we need to count the records based on some filters. For example, count all the objects where the type is equal to ‘P’. For that, we basically need to add the field and the text condition to the XPath query:
varFilterCount = System.Convert.ToInt32(xpath(msgInput,”count(//*[local-name()=’XMLSample’]/*[local-name()=’Object’]/*[local-name()=’Type’][text()=’P’])”));
Of course, this can become more complex, but the beauty is that XPath is prepared to handle all, or almost all, your needs. For example, count all objects where Type is ‘P’ or ‘C’:
varFilterCount = System.Convert.ToInt32(xpath(msgInput,”count(//*[local-name()=’XMLSample’]/*[local-name()=’Object’]/*[local-name()=’Type’][text()=’P’ or text()=’C’])”));
You can access and download this sample code from GitHub here: POC: BizTalk – Count XML Nodes Inside Orchestrations