Monday, May 03, 2010

Sorting Elements in BPEL

This is a continuation of my previous two post.We have so far designed a process for receiving multiple input from client and then assign it to the output variable.In this exercise we will try to sort the output elements based on some particular element.

We will use the basic functionality of XSL and use the xsl:sort to achieve this.As definition says

To sort the output simply add an element inside the element in the XSL file.Now we will see how we can achieve this in our BPEL process.

Few instructions your jdeveloper will hang definitely if you are going to make any change as jdeveloper is not very comfortable with transformation activity.It really frustrated me lot of times while i was working on this.

you are very much supposed to get this famous FOTY0001: type error

which means you have made some mistake in your XSLT.A common error of this type is

XPath expression failed to execute.
Error while processing xpath expression, the expression is "ora:processXSLT('Transformation_1.xsl',bpws:getVariableData('inputVariable','payload'))", the reason is FOTY0001: type error.
Please verify the xpath query.

There is no perfect solution for this error ,all you need to do is just check if your xml code is correct.You can use the xpath evaluator to evaluate whether the xpath you have mentioned is correct.Verify whether the input and output variable mentioned are correct or not.

Ok now we will just desing our bpel process again.All we need to do is to change our transformation.

We will make use of two XXSLT construct over here

one is which is clear from name itself is used to sort the elements

and we will also use element which creates a copy of the current node.This element can be used to insert multiple copies of the same node into different places in the output.

Now we will see how we are making the changes,Just to make it easy for you i will just copy paste the transformation that i have used at my end then we will check how we have designed it.

The content within my Transformation_1.xsl is

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions"
xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20"
xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ora="http://schemas.oracle.com/xpath/extension"
xmlns:ehdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.esb.server.headers.ESBHeaderFunctions"
xmlns:orcl="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"
xmlns:ids="http://xmlns.oracle.com/bpel/services/IdentityService/xpath"
xmlns:hwf="http://xmlns.oracle.com/bpel/workflow/xpath"
xmlns:transform="http://xmlns.oracle.com/BPELProcess1"
exclude-result-prefixes="xsl xref xp20 bpws ora ehdr orcl ids hwf">
<xsl:template match="/">
<transform:BPELProcess1ProcessResponse>
<xsl:for-each select="/transform:BPELProcess1ProcessRequest/transform:listElement/transform:itemValue">
<xsl:sort/>
<xsl:copy-of select="../transform:itemID"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</transform:BPELProcess1ProcessResponse>
</xsl:template>
</xsl:stylesheet>

Just copy paste this in to your transformation and don't bother about the design of this transformation as the jdeveloper has bug because of which we can not see the design.

Now i will try to explain you what all has been done in this XSL

As you can see i have added one extra namespace

xmlns:transform="http://xmlns.oracle.com/BPELProcess1"

this is because i want that the XSL that i have created should be stored in this namespace.

Since i am designing the XSL i will initiate all the variables which i have defined by my own with the prefix transform.


Rest all like for-each,copy-of and sort are predefined in the following namespace

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

Now the very first statement in my XSL is

xsl:for-each select="/transform:BPELProcess1ProcessRequest/transform:listElement/transform:itemValue"

By which i mean that for each element "itemValue" in the input

then the next is xsl:sort which says sort in order of "itemValue"

and when this criteria is fullfilled do following

<xsl:copy-of select="../transform:itemID"/>
<xsl:copy-of select="."/>

Here again we need to understand two things

the . (dot) operator is used to locate the current node.

So by saying xsl:copy-of select="."

i mean copy the itemValue here as i have already selected my currrent node as

/transform:BPELProcess1ProcessRequest/transform:listElement/transform:itemValue"

Again in this <xsl:copy-of select="../transform:itemID"/>

I have used "../transform:itemID"

here .. (double dot is an xpath syntax) which mean parent of the current node.

So the parent of current node will be one level up that is

/transform:BPELProcess1ProcessRequest/transform:listElement

so we reached to this place by defining .. and then we add the element transform:itemID

So the itemID will be copied to this place.

I believe i have tried my best to make it very clear.so now when you have understood the code.Just save the code and deploy it.

Now go to the console and try to check how does it work.


This is the input variable i m taking





I have taken same value for itemID as i have sorted my elements on basis of itemValue.

i got the following response.



As you can see i have provided the input in a random order but the output is in a sequence .

You can use this concept to design process where in output is required to be generated in a sequential order.This is a very common scenario where in input files are also required to be processed in a sequence using file/ftp adapter.I will cover that sometimes later.

No comments: