XSL Transformation Filter

Data manipulation through Customizations can be very powerful, however in the SOA environment, working with XML data, developers are often used to working with XSL transformations to manipulate XML data. Working with transformations can have several advantages over creating a Java Class, for example, transformation are very powerful in manipulating collections.

This is exactly the reason why we’ve build in support for XSL transformations within the XML Data Control. This is achieved with the help of a special Data Provider that can be nested.
Nesting Data Providers get their XML from the nested provider and can manipulate it before returning it to the caller.
 

In the above example, we nest the resource data provider with an XSL Transform Filter, this data provider also takes one parameter which is the actual stylesheet. This stylesheet will be applied to the returned XML data from the resource data provider.

As a starting point, we'll use the DataControl based on the HR WebService we've seen earlier:

<AdapterDataControl id="HRXslDatacontrol" FactoryClass="oracle.adf.model.adapter.DataControlFactoryImpl"
                        ImplDef="org.adfemg.datacontrol.xml.DataControlDefinition" SupportsTransactions="false"
                        SupportsSortCollection="false" SupportsResetState="false" SupportsRangesize="false"
                        SupportsFindMode="false" SupportsUpdates="false"
                        Definition="org.adfemg.xmlsample.HRXslDatacontrol"
                        BeanClass="org.adfemg.xmlsample.HRXslDatacontrol"
                        xmlns="http://xmlns.oracle.com/adfm/datacontrol">
        <Source>
            <definition xmlns="http://adfemg.org/adfm/datacontrol/configuration"
                        schema="http://xmldc-sample.appspot.com/HR.xsd" schema-root="DepartmentEmployeesResponse"
                        dc-operation="getDeptEmps">
                <data-provider class="org.adfemg.datacontrol.xml.provider.data.WSDataProvider">
                    <parameters>
                        <parameter name="endPointUrl" value="http://xmldc-sample.appspot.com/HumanResourcesService"/>
                        <parameter name="soapVersion" value="1.1"/>
                        <xml-parameter name="requestElement">
                            <![CDATA[ <DepartmentEmployeesRequest xmlns="http://adfemg.org/HR">
                                             <departmentId>30</departmentId>
                                          </DepartmentEmployeesRequest>
                                ]]>
                        </xml-parameter>
                    </parameters>
                </data-provider>
            </definition>
        </Source>
    </AdapterDataControl>


Resulting in the following DataControl:


Now we need a few things to set up the DataControl:

  1. The source XSD: HR.xsd.
  2. The target XSD: HRflat.xsd.
  3. The XSL transformation: HRtoHRflat.xsl.

Since this is an example of how the XML DataControl can work with xsl, this is a very simple example of an xsl.
In the source XSD we have an element employee with job info as child element, but in the target XSD we have an employee with the elements from job directly under the employee.
The xsl transformation takes the job info and puts it into the elements under the employee.

In the DataControls.dcx we need to edit the datacontrol definition so it will use the xsl transformation on the result of the webservice.
The XML DataControl is set up to support nested data-providers, meaning we can create a parent node data-provider that wraps the WebService dataprovider. 

The result of the correctly configured datacontrol will look like this:

<AdapterDataControl id="HRXslDatacontrol" FactoryClass="oracle.adf.model.adapter.DataControlFactoryImpl"
                        ImplDef="org.adfemg.datacontrol.xml.DataControlDefinition" SupportsTransactions="false"
                        SupportsSortCollection="false" SupportsResetState="false" SupportsRangesize="false"
                        SupportsFindMode="false" SupportsUpdates="false"
                        Definition="org.adfemg.xmlsample.HRXslDatacontrol"
                        BeanClass="org.adfemg.xmlsample.HRXslDatacontrol"
                        xmlns="http://xmlns.oracle.com/adfm/datacontrol">
        <Source>
            <definition xmlns="http://adfemg.org/adfm/datacontrol/configuration"
                        schema="/org/adfemg/xmlsample/trans/HRflat.xsd" schema-root="DepartmentEmployeesFlat"
                        dc-operation="getDeptEmps">
                <data-provider class="org.adfemg.datacontrol.xml.provider.filter.XSLTransformFilter">
                    <parameters>
                        <parameter name="stylesheet" value="/org/adfemg/xmlsample/trans/HRtoHRflat.xsl"/>
                    </parameters>
                    <data-provider class="org.adfemg.datacontrol.xml.provider.data.WSDataProvider">
                        <parameters>
                            <parameter name="endPointUrl"
                                       value="http://xmldc-sample.appspot.com/HumanResourcesService"/>
                            <parameter name="soapVersion" value="1.1"/>
                            <xml-parameter name="requestElement">
                                <![CDATA[ <DepartmentEmployeesRequest xmlns="http://adfemg.org/HR">
                                             <departmentId>30</departmentId>
                                          </DepartmentEmployeesRequest>
                                ]]>
                            </xml-parameter>
                        </parameters>
                    </data-provider>
                </data-provider>
            </definition>
        </Source>
    </AdapterDataControl>


To come to this datacontrol definition, follow these steps:

  1. Edit the schema location to make it point the target xsd located within the project.
  2. Edit the schema root to match the value returned by the xsl.
  3. Add a new data-provider, with the class: org.adfemg.datacontrol.xml.provider.filter.XSLTransformFilter
  4. Add a child node parameters.
  5. Within the parameters node add a parameter with the name stylesheet and the value set to the location of the stylesheet.
  6. Make sure the original webservice data-provider is now a child element within the xsl data-provider after the parameters node.
  7. Make sure you add an extra closing tag between the </data-provider> end tag en the </definition> end tag.

Refresh your Data Controls panel within JDeveloper:


Now your DataControl is all set up to be used in a page.
Within JDeveloper, create a new page called "HRflat".
Drag and drop the Employee from your DataControl on the newly created page:



Choose ADF Form, so the Create Form dialog will popup:
In the create Form dialog, select the Row Navigation and the submit button and press OK:


Right mouse click in your page and select run/debug to view the result:


The HRflat page will open and you will be able to navigate through the rows: