Monday, April 12, 2010

Multiple Source Transformation in BPEL

There will be many instances in your project where you will be having requirements to transform data from multiple sources into a single destination. An example scenario will be the need to do selective data enrichment (from a different source) to a collection of existing records. Currently multiple source transformations are not supported out of the box in 10g. Only single source can be mapped to single destination. As always there is a workaround for every problem. I will list down the steps for the workaround .In one of my previous blog that I had written on Payload splitting using XSL uses similar steps.

There is a pre-requisite for this, a schema. In case you are using AIA below is the location

<xsd:import namespace="http://schemas.oracle.com/service/bpel/common" schemaLocation="http://<hostname>:<port>/AIAComponents/UtilityArtifacts/bpel-common.xsd" />

Or else you have create your own custom XSD

Code Snippet :: Custom schema - Param.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:p="http://schemas.oracle.com/service/bpel/common"

xmlns="http://schemas.oracle.com/service/bpel/common"

targetNamespace="http://schemas.oracle.com/service/bpel/common"

elementFormDefault="qualified">

<xsd:element name="parameters">

<xsd:complexType>

<xsd:sequence>

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

<xsd:complexType>

<xsd:sequence>

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

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

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:schema>

1. Initialization

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

2. Assign XML fragment mentioned below to the parameters

Code Snippet :: XML fragment in Assign

<assign name="AssignXMLFragment">

<copy>

<from>

<common:parameters xmlns:common="http://schemas.oracle.com/service/bpel/common">

<common:item>

<common:name>InputDataFromSource2</common:name>

<common:value/>

</common:item>

</common:parameters>

</from>

<to variable="Params" query="/common:parameters"/>

</copy>

</assign>

3. Read the data from second source using a ora:getContentAsString() function into the InputDataFromSource2 parameter

Code Snippet :: Assign in .bpel file

<assign name="AssignDataFromSource2To Params">

<copy>

<from expression="ora:getContentAsString(bpws:getVariableData('InputSource2Msg','InputParameters','/ns12: InputParameters'))"/>

<to variable="Params" query="/common:parameters/common:item[common:name=' InputDataFromSource2']/common:value"/>

</copy>

</assign>

4. Now we will use transformations leveraging the feature of Passing Parameters into XSLT. We will pass the data in Params variable as the 3rd parameter so that it can be accessed in the XSL

Code Snippet :: Assign in .bpel file

<assign name="MultipleSourceTransformation">

<copy>

<from expression="ora:processXSLT('Xform_From_Two_Sources.xsl',bpws:getVariableData('inputVariable','TestInABM','/ns8:'TestABM'),bpws:getVariableData('Params'))"/>

<to variable="outputVariable" part="TestOutABM”/>

</copy>

</assign>

5. Inside the XSL we will be accessing the Param data using xsl:param tag . The entire data will be available in the InputDataFromSource2 parameter. We will use orcl:parseEscapedXML function to convert the string data into proper XML format.

Code Snippet :: .xsl file

<xsl:stylesheet>

………………………………

…………………………………

<xsl:param name="InputDataFromSource2">

<xsl:text disable-output-escaping="yes"><test:InputSource2Msg

xmlns:test="http://xmlns.geo.com/test/"/></xsl:text>

</xsl:param>

<xsl:variable name="Source2Data"

select="orcl:parseEscapedXML($InputDataFromSource2)"/>

6. After step 5 the data in XML format will be available in Source2Data variable which can be used as any other variable definition and all child elements can be accessed using this variable.

Code Snippet :: .xsl file

…………………………………

<geo:FirstName>

<xsl:value-of select=”$Source2Data /test:inputData/test:First_Name"/>

</geo: FirstName >

That’s it.. Compile and deploy. You will be able to access the data from different sources in same XSL.

1 comment:

Anonymous said...

Awesome article, thank you very much!!