WSO2 BPS extends the default XPath coverage provided by the WS-BPEL specification mostly by adding support for XPath 2.0 and by offering a few utility extension functions to make some assignments easier.
To use XPath 2.0 in processes, use the following queryLanguage and expressionLanguage attributes:
queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0"expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0"
To make the XPath 2.0 default for the process, add these attributes to the root process element. If you want to stick with XPath 1.0 but want XPath 2.0 support for a specific assignment, you can also define these attributes on an assign element.
All extension functions are defined in the ODE extension namespace: http://www.apache.org/ode/type/extension. This namespace will be associated with the ode prefix in the following examples.
This is a function that allows you to insert one or more siblings (specified by the $siblings argument in the signature below) before the first node of children (specified by the $children argument), all of whose nodes must have the same parent (specified by the $context argument).
ode:insert-before($contextas node(),$childrenas node()*,$siblingsas node()*)as node()
By design, this function is non-updating in that it preserves the identity and properties of its arguments (i.e., they don't try to change the XML in-place). Instead, a modified copy of the context node is created, essentially giving it a new identity. Further, it returns a single R-value item, as opposed to a sequence. The example below illustrates how it may be used in the context of an assign activity:
<assign><copy><from>ode:insert-before($parent, $parent/child::node[position()=last()], $siblings)</from><tovariable="parent"/></copy></assign>
For those familiar with the XQuery Update Facility , the above example is semantically equivalent to the expression shown below:
insert nodes $siblings before $parent/child::node[position()=last()]
ode:insert-after($contextas node(),$childrenas node()*,$siblingsas node()*)as node()
By design, this function is non-updating in that it preserves the identity and properties of its arguments (i.e., they don't try to change the XML in-place). Instead, a modified copy of the context node is created, essentially giving it a new identity. Further, it returns a single R-value item, as opposed to a sequence. The example below illustrates how it may be used in the context of an assign activity:
<assign><copy><from>ode:insert-after($parent, $parent/child::node(), $siblings)</from><tovariable="parent"/></copy></assign>
For those familiar with the XQuery Update Facility , the above example is semantically equivalent to the expression shown below:
insert nodes $siblings after $parent/child::node()
ode:insert-as-first-into($contextas node(),$childrenas node()*)as node()
By design, this function is non-updating in that it preserves the identity and properties of its arguments (i.e., they don't try to change the XML in-place). Instead, a modified copy of the context node is created, essentially giving it a new identity. Further, it returns a single R-value item, as opposed to a sequence. The example below illustrates how it may be used in the context of an assign activity:
<assign><copy><from>ode:insert-as-first-into($parent, $children)</from><tovariable="parent"/></copy></assign>
For those familiar with the XQuery Update Facility , the above example is semantically equivalent to the expression shown below:
insert nodes $childrenas first into $parent
ode:insert-as-last-into($contextas node(),$childrenas node()*)as node()
By design, this function is non-updating in that it preserves the identity and properties of its arguments (i.e., they don't try to change the XML in-place). Instead, a modified copy of the context node is created, essentially giving it a new identity. Further, it returns a single R-value item, as opposed to a sequence. The example below illustrates how it may be used in the context of an assign activity:
<assign><copy><from>ode:insert-as-last-into($parent, $children)</from><tovariable="parent"/></copy></assign>
For those familiar with the XQuery Update Facility , the above example is semantically equivalent to the expression shown below:
insert nodes $childrenas last into $parent
ode:delete($contextas node(),$childrenas node()*)as node()
By design, this function is non-updating in that it preserves the identity and properties of its arguments (i.e., they don't try to change the XML in-place). Instead, a modified copy of the context node is created, essentially giving it a new identity. Further, it returns a single R-value item, as opposed to a sequence. The example below illustrates how it may be used in the context of an assign activity:
<assign><copy><from>ode:delete($parent, $children)</from><tovariable="parent"/></copy></assign>
For those familiar with the XQuery Update Facility , the above example is semantically equivalent to the expression shown below:
delete nodes $childrenode:rename($contextas node(),$nameas item())as node()
By design, this function is non-updating in that it preserves the identity and properties of its arguments (i.e., they don't try to change the XML in-place). Instead, a modified copy of the context node is created, essentially giving it a new identity. Further, it returns a single R-value item, as opposed to a sequence. The example below illustrates how it may be used in the context of an assign activity:
<assign><copy><from>ode:rename($person, fn:QName("http://www.example.com/example", "manager"))</from><tovariable="person"/></copy></assign>
For those familiar with the XQuery Update Facility , the above example is semantically equivalent to the expression shown below:
rename$personas fn:QName("http://www.example.com/example","manager")
Assign Assumption
The WS-BPEL requires that "for a copy operation to be valid, the data referred to by the from-spec and the to-spec MUST be of compatible types." Hence, make sure that when you rename an element, the new name refers to a type that is compatible with the target variable. In other words, it should be of a substitutable (essentially stronger) complex type.
<assign><from>ode:split-to-elements($authorizeMessage.credential/userList, ',', 'user')</from><to>$authorizedUsers</to></assign>
If the source element contains a list like "joe, paul, fred" the target variable will be assigned the sequence of elements:
<user>joe</user><user>paul</user><user>fred</user>
Alternatively this function can take a fourth parameter that would be the namespace of the elements used to wrap the split strings:
ode:split-to-elements(stringToSplit, separator, targetElement, targetNamespace)
NOTE:This function was formerly known as splitToElements, which may still be used, but is deprecated.
ode:dom-to-string($nodeas node())as xs:string
This is a function that allows you to retrieve the value of a property, defined in deploy.xml for the current process, with the given name (specified by the $name argument in the signature below, which is either a QName, String, Element or Single-Valued List).
ode:process-property($nameas item())as node()
Basically, this method gives you a way to reference properties, defined in deploy.xml for a given process, directly in the BPEL code for that process. The $name argument refers to any schema item that resolves to a QName. The return value is the child node of the property element with the given name.
The example below illustrates how it may be used in the context of an assign activity:
<assign><copy><from>ode:process-property("auctionEpr")</from><topartnerLink="partnerLink"/></copy></assign>
where, the property called "epr" is defined in the corresponding deploy.xml as follows:
<deployxmlns="http://www.apache.org/ode/schemas/dd/2007/03"xmlns:tns="http://ode/bpel/process"><processname="tns:negotiate"><propertyname="auctionEpr"><sref:service-refxmlns:sref=" http://docs.oasis-open.org/wsbpel/2.0/serviceref"xmlns:addr="http://example.com/addressing"xmlns:as="http://example.com/auction/wsdl/auctionService/"><addr:EndpointReference><addr:Address>http://example.com/auction/RegistrationService</addr:Address> <addr:ServiceName>as:RegistrationService</addr:ServiceName></addr:EndpointReference></sref:service-ref></property>... </process></deploy>