Wednesday, January 13, 2010

How to implement Payload Splitting using XSLT in BPEL

This blog is on the implementation details of how to process huge XML payload files in smaller chunks. As you know out of memory happens because XSL transformation and translation leaves huge memory footprint and it proportionally grows with XML payload size. In order to avoid that what we have done is to parse the XML in smaller chunks. To implement this we brought in indexes to XSL transformation. This is done using a begin Index and end Index which will be dynamically passed into the XSL. It helped in getting control on the no.of records being transformed for processing.

I will list down some important steps that were followed as part of the prototype we had developed before implementing it in real time scenarios.

To start with we created 2 BPEL processes – PayloadSplitter and PayloadProcessor

PayloadSplitter will have the logic for breaking down the XML payload into smaller chunks. PayloadProcessor will have the logic required for processing the payload. I will be focusing only PayloadSplitter as that takes of managing the payload.


  1. Initialization

a. Create a Variable params which should be of type parameters(Refer Param.xsd)

b. Create a variable totalCount for storing the no of records in the payload.

c. Create a variable incrementSize for storing the no of records that needs to be processed in each loop.

d. Create a variable currentIndex for storing the end index of the records processed in each loop.

For eg:-If we have 100 records to be processed and 5 records needs to be processed in each loop.

totalCount = 100 & incrementSize = 5. currentIndex for first loop will be 5 as it will be initialized as incrementSize.

For 2nd loop currentIndex will be 10(currentIndex + incrementSize) and so on

Code Snippet :: Custom schema - Param.xsd

<xsd:schema xmlns:xsd=""





<xsd:element name="parameters">



<xsd:element name="item" minOccurs="1" maxOccurs="unbounded">



<xsd:element name="name" type="xsd:string"/>

<xsd:element name="value" type="xsd:string"/>








  1. Assign XML fragment mentioned below to the parameters

Code Snippet :: XML fragment in Assign

<bpelx:assign name="Assign_ParamNames">



<parameters xmlns="">











<to variable="params" query="/ns2:parameters"/>


3. Assign 0 as the begin index to /ns2:parameters/ns2:item[1]/ns2:value .

(You will have to manually edit the index value[i] in the XPath tab)


<from expression="'0'"/>

<to variable="params" query="/ns2:parameters/ns2:item[1]/ns2:value"/>


4. Assign incrementSize as the end index to /ns2:parameters/ns2:item[2]/ns2:value

(You will have to manually edit the index value [i] in the XPath tab)


<from variable="incrementSize"/>

<to variable="params" query="/ns2:parameters/ns2:item[2]/ns2:value"/>


  1. Initialize currentIndex as incrementSize (only for first loop)
  2. Now starts the while loop which will process records in smaller chunks.

Condition check : totalCount > 0

Inside the while loop we will be having 3 main activities.

a) Transform the payload in smaller chunks to the format expected by PayloadProcessor

b) Invoke the payload processor (invoke activity along with a partner link to PayloadProcessor)

c) Assign activity to update the loop variables for the next run of the loop.

  1. Have a XSLT transform activity where we will be leveraging the feature of Passing Parameters into XSLT.

Refer Ram Kumar’s article :Passing BPEL Variable contents into XSLT as Parameters

We will pass the params variable to the XSL which is populated with beginIndex and endIndex values for first loop.

The transformation from the payload variable will happen to the input variable of the Payload Processor.

Code Snippet :: .bpel file

<assign name="Transform_1">





<from expression="ora:processXSLT('Transformation_1.xsl',


bpws:getVariableData('params') )"/>

<to variable="invokeProcessInputVariable" part="payload"/>



Code Snippet :: .xsl file




<xsl:param name=" beginIndex"/>

<xsl:param name="endIndex "/>

<xsl:template match="/">


<xsl:for-each select="/ns1:PayloadSplitterProcessRequest/ns1:inputData">

<xsl:if test="(position() > $ beginIndex) and (position() <= $ endIndex)">










  1. Have an invoke activity to call the PayloadProcessor .PayloadProcessor BPEL process should contain the logic to process the payload.
  2. In assign Activity

a) TotalCount = TotalCount - incrementSize

b) Assign endIndex to beginIndex for next loop.


<from variable="params"


<to variable="params"



c) currentIndex = currentIndex + incrementSize

d) Assign currentIndex to endIndex.


<from expression="bpws:getVariableData('currentIndex')"/>

<to variable="params"




That’s pretty much the logic required for creating Payload Splitter .Special thanks to Srinivas Kommanaboyina who had worked on developing this prototype.

No comments: