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
<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.