How to fetch a particular node value from a set of XML nodes in BPEL 11g

In my case, I have used the Human task in my BPEL process. For every Human task added into BPEL process, a global task complex variable will get created. This complex variable contains all the parameters related to a task. Out of them Comment is one parameter which contains the comments entered by the Approvers or all participants in the task.

At every step in the workflow, the Approver can enter comments in the task details page. After the comments are updated I need to make an insertion it into Audit History table from BPEL process. So if the Approver enters one comments in task details page I’m able to successfully pick the entered value from the Comment parameter under  task complex variable. In this case as there will be only one value in the Comments Node.

But if the Approver enters multiple comments say more than one in the task details page, then I was not able to read the value from Comments Node. I used to get the below error –

“{http://schemas.xmlsoap.org/ws/2003/03/business-process/}selectionFailure” has been thrown.
-<bpelFault>
<faultType>0</faultType>
-<selectionFailure xmlns=”http://schemas.xmlsoap.org/ws/2003/03/business-process/”&gt;
-<part name=”summary”>
<summary>
XPath query string returns multiple nodes.
The assign activity part and query /task:task/task:userComment/task:comment are returning multiple nodes.
The assign activity part and query named in the error message returned multiple nodes. It should return single node.
According to BPEL4WS specification 1.1 section 14.3, the assign activity part and query named in the error message should not return multiple nodes. Verify the part and xpath query named in the error message at line number 1074 in the BPEL source.
</summary>
</part>
</selectionFailure>
</bpelFault>

After spending much time to resolve this issue, I found one solution which worked fine in my case.

Solution 1:

We have ora:getElement(variableName, partName, locationPath, index) xpath function available in the BPEL by default. The parameter details for this function is as below –

This function returns an element  using index from the array of elements. The signature of this function is  ora:getElement(variableName, partName, locationPath, index).

The arguments are:

1) variableName – the source variable for the  data,

 2) partName – the part to select from the variable (required), 

 3) locationPath – provides an absolute location path  (with / meaning the root of the document fragment representing  the entire part) to identify the root of a subtree within the  document fragment representing the part required).

 4) index – dynamic index value. the index of the first node is 1.

So below is the way my code looks like

ora:getElement(‘NewSupplierRequestHumantask_1_globalVariable’,’payload’,’/task:task/task:userComment/task:comment’,ora:countNodes(‘NewSupplierRequestHumantask_1_globalVariable’,’payload’,’/task:task/task:userComment/task:comment’))

The arguments are:

1) variableName – NewSupplierRequestHumantask_1_globalVariable,

 2) partName – payload (required),

 3) locationPath – /task:task/task:userComment/task:comment

4) index – ora:countNodes(‘NewSupplierRequestHumantask_1_globalVariable’,’payload’,’/task:task/task:userComment/task:comment’).

For the parameter Index, you can specify the static value (2 or 4 or 8 etc..) or in my case I want to specify the dynamic value which is the last node, so I used the  ora:countNodes(variableName, partName?, locationPath?).

 This function returns size of elements as an integer.The signature of this function is ora:countNodes(variableName, partName?, locationPath?).  The arguments are:

 1) variableName – the source variable for the data,

2) partName – the part to select from the variable (optional),

3)locationPath – provides an absolute location path (with / meaning the root of the document fragment representing the entire part) to identify the root of a subtree within the document fragment representing the part (optional).

Solution2:

let’s say you have a collection of Books:
<BOOKS>
<BOOK>
<NAME>Alchemist</NAME>
<AUTHOR>Paulo</AUTHOR>
</BOOK>
<BOOK>
<NAME>Red-Book</NAME>
<AUTHOR>IBM</AUTHOR>
</BOOK>

</BOOKS>

The Simpler solution would be:
1) Assign the Count of the nodes(more or less like finding length or size of the collection) in a Variable (say totalCommentsCount) using ora:countNodes(‘NewSupplierRequestHumantask_1_globalVariable’,’payload’,’/task:task/task:userComment/task:comment’) function.
2) Create a counter variable and initialize with value 1.
3) Put a WHILE activity saying till (counter<totalCommentsCount).
4) iterate and in each loop extract the node using:
bpws:getVariableData(‘NewSupplierRequestHumantask_1_globalVariable’,’payload’,concat(‘/task:task/task:userComment[‘, bpws:getVariableData(‘counter’), ‘]/task:comment’))
e.g. its like using it as an array: /ns37:BOOKS/ns37:BOOK[1]/ns37:NAME => Alchemist
5) Increment the counter by 1 inside the While Loop

 Both solution works fine. If you just want to take the last node in the xml values, better to follow first solution. But in case if you want to get any node value from between, you can follow the second solution and use the conditions as like the node value is equals to some value, assign that required value to another variable inside the While loop.

 

Advertisements
This entry was posted in BPEL, Oracle Business Process Management (BPM), Service Oriented Architecture (SOA 11g) and tagged , , , , , . Bookmark the permalink.

2 Responses to How to fetch a particular node value from a set of XML nodes in BPEL 11g

  1. Seema says:

    In solution 1 are you looking for only the last comment?

  2. Peter A says:

    This worked for me! Thank you very much

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s