Thursday, December 2, 2010

Some XPath functions useful in BPEL


In BPEL programming, XPath is heavily used to manipulate XMLs. Here are some WS-BPEL specific XPath functions and common xpath functions that’ll be helpful in writing BPELs . Remember based on the BPEL run-time engine; functionalities of these functions might be changed.

There are some valuable BPEL run time engine related XPath functions, you need to know in XML manipulations.


bpel:getVaribleData(varName, partName, xpathStr) - This function is not defined in WS-BPEL-2.0 specification. But this works in WSO2-BPS and Apache-ODE. It can be used to extract a set of elements from a variable, using a XPath expression.

eg -
<bpel:copy>
    <bpel:from>
        <![CDATA[count(bpel:getVariableData(‘$Variable','$partName')/ns:return)]]>
    </bpel:from>
    <bpel:to variable="itemCount"></bpel:to>
</bpel:copy>

Remember to use ‘’ when passing varName and partName. And here “/ns:return” is the xpath expression.


bpel:getLinkStatus() - This is also not defined in WS-BPEL-2.0 specification. It evaluates and return a boolean whether a particular link is active/inactive.


bpel:getVariableProperty(string, string) - This is helpful in extracting properties in Variables.

eg - (From http://docs.oasis-open.org/wsbpel/2.0/OS/wsbpel-v2.0-OS.html)
<condition>
    bpel:getVariableProperty('stockResult','inventory:level') > 100
</condition>

Remember to use ‘’ when passing parameters.


bpel:doXSLTTransform() - perform XSLT transformations.

eg - (From http://docs.oasis-open.org/wsbpel/2.0/OS/wsbpel-v2.0-OS.html)
<copy>
    <from>
        bpel:doXslTransform("urn:stylesheets:A2B.xsl", $A)
    </from>
    <to variable="B"/>
</copy>


round(input) - used to get an integer closest to the $input. This is become important in converting numbers into integers.

eg - In arrays mostly need to use this operation to traverse.
<bpel:copy>
    <bpel:from>
        <![CDATA[$profileProcessorInput.payload/tns:profiles/tns:profile[round($itemIterator)]/]]>
    </bpel:from>
    <bpel:to variable="itemLine">
        <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
            <![CDATA[@name]]></bpel:query>
    </bpel:to>
</bpel:copy>


string() - In WSO2 BPS and Apache ODE this method can be used to extract text content out-of elements rather using /text() .



string-length() - Name suggests what it does. But != operator seems not to work with the output from this function. So you can use > or < rather using != .


Avoid name-spaces in xpath manipulation - It becomes cumbersome sometime to concern on name-spaces when it’s not that much essential. We can use Regular expressions to bypass the name-space verification on XPath. eg -
<bpel:copy>
<bpel:from part="payload" variable="profileContext">
<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
<![CDATA[tns:profiles/*[local-name() = 'Profile'][round($itemIterator)]/*[local-name() = 'club_code']]]>
</bpel:query>

</bpel:from>
<bpel:to part="parameters" variable="Request">
<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
<![CDATA[ns2:BuildingNo]]>

</bpel:query>
</bpel:to>
</bpel:copy>


contains($regEx, $string) - use to match a $string with a particular $substring. Here you can use Reg-Ex as well.


count() - Returns the count of nodes. Here’s an example of it.

eg -
<bpel:copy>
    <bpel:from>
        <![CDATA[count(bpel:getVariableData('$VariableName','$partName')/ns:SubChildElementName)]]>
    </bpel:from>
    <bpel:to variable="itemCount"></bpel:to>
</bpel:copy>

14 comments:

kinghomer said...

Hi Denis,
my name is Giuseppe and i come from Italy. I arrived here by google when i was searching XPATH for BPEL.
Maybe you can help me :) !!
I'm developing simple web services on JBOSS 5.1 based on BPEL that run by Riftsaw.
My goal is:
1 Web services which takes in input a Username and provides it in output
1 Web services which takes in input previous username and a password, and provides them in output
1 Web services which takes in input previous username and password string, and return to output 'TRUE' of 'FALSE' if login parameters are verified.
I don't know how use XPATH for doing it. Actually i studied only the way for concat a string to the input by SayHello example, which located in riftsaw subfolder.

Can you help me ???

Denis Weerasiri said...

Hi Giuseppe,
Based on your requirement,
XPath is need for
1. extract input parameters from incoming messages to bpel(like username, password etc)
2. create the request variables (to add username and password to the request message of the particular web service)

So you can easily do this, without even using XPath functinos I've mentioned here.

Arrivederci :)
Denis Weerasiri

Denis Weerasiri said...

Hi Giuseppe,
This article will help you. The sample explained here use the same type of logic you mentioned in the first comment.

http://wso2.org/library/articles/writing-simple-ws-bpel-process-wso2-bps-apache-ode

Arrivederci :)
Denis Weerasiri

Denis Weerasiri said...

Hi Denis,First thank you for your postings..I have one query can please help me.

I have to write time based scheduling in BPEL, is this is possible in BPEL, how write to the time based properties in BPEL.Could you please explain me,

Thanks in Advance

Anil

Denis Weerasiri said...

Hi Anil,

You should have a look at "onAlarm" construct. https://www.oasis-open.org/committees/download.php/23964/wsbpel-v2.0-primer.htm#_Toc166509708

Denis Weerasiri said...

Thank you Denis,But how can i give same at the run time.means while i am testing the data from ''TRY-IT'' EDITOR in BPS Server , How would i give time dynamically in 'TRY-IT'' EDITOR in BPS Server.

Denis Weerasiri said...

Thank you Denis,But how can i give time at the run time.means while i am testing the data from ''TRY-IT'' EDITOR in BPS Server ,How would i give time dynamically in 'TRY-IT'' EDITOR in BPS Server,And even i need to escalate the same as Manager wise like" time over,escalating to your manager ", .Please guide me.

Denis Weerasiri said...

Hi Anil,
I did not use BPS for over a year now. So it's better if you can ask from WSO2 Community.

Denis Weerasiri said...

Hi,
I have problem with substring functions. At first I get message with element type=anyType.








output variable with message is





0



then BPEL assign do









returns



0


or string($newMessageCountResponse.parameters) returns

0

I don't know how to get rid of with temporary-simple-type-wrapper.
Because even when variable newMessageCount is type string I cannot do substring.
Every substring function (for example substring($newMessageCount, 20, 1)) ends with

I use WSO2 BPS 3.2.0

Thank you

Denis Weerasiri said...

Hi,
It seems I did not get your full message. I only see it partially. Could you please send me your full request in plain text?

Denis Weerasiri said...

Hi, I wrote long message about problem with extracting XML from anyType element to string but then I found that is default element of simple type variable. So then I edited my message.

Denis Weerasiri said...

That's great

Denis Weerasiri said...

Hi Denis!
You have written that its possible to give regular expressions as parameters of contains() function. I've tried, but it seems that this function doesn't support use of regular expressions.

Denis Weerasiri said...

Hi,
I have to get base64 encoded content from WS and send it to another WS. WS returns message




Test_001
Text ....

iVBORw0KGgoAAAANSUhEUgAABU4AAAJMCAYAAAAlqjx9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAJswSURBVHhe7N15fBVVnv9//8eKwyHM2Oap2QEAAACgj6IitKtHi9PT09N0f38fPhwAAAAA4C2KitCuzs7Oyo40LE6vrq7S+fl5ms1m4QYAAAAAAN6aqAjtKnejOWFxmnN5eVm2q/loKgAAAADAkOUutCpNc1qLUxEREREREREREZH/axSnIiIiIiIiIiIiIhtJ6T84e1xlyXhQJgAAAABJRU5ErkJggg==



I have problem to assign content of Object element to input variable of WS.

$WebServicePLResponse2.return/skt:Body/msc:MessageContainer/msc:Object[round($Counter)]
returns null and set all attributes

$WebServicePLResponse2.return/skt:Body/msc:MessageContainer/msc:Object[round($Counter)]/text()
ends with exception

string($WebServicePLResponse2.return/skt:Body/msc:MessageContainer/msc:Object[round($Counter)])
returns null

bpel:getVariableData('WebServicePLResponse2','return')/skt:Body/msc:MessageContainer/msc:Object[round($Counter)]
returns null for base64 but works for XML content

Please tell me how to get base64 encoded content from message.
I am using wso2bps-3.2.0 and Eclipse Version: Kepler Service Release 2,
buildId 4.3.2.M20140221-1700 with WSO2 BPEL plug-in 2.0.0

Thank you in advance