Thursday, July 22, 2010

Remove duplicates from an input XML using XSLT

It is often the case that an input XML may contain duplicate data. It might be necessary to filter the duplicate data using a unique identifier, also from the input and send only the non-repeating, unique data to the output. In these cases, this transformation can be used to filter the data in the input.
This can be better understood by mapping this case to a real time scenario. Let us assume an organization having employees who can work in more than one department. If the input is going to contain the list of employees based on the department, there will be some employees whose data can repeat, as they are part of more than one department. If we need to filter the result based on the employee id to get a set of non-repeating unique employees, this logic can be used.

The implementation of this logic has been done using the function “following::”. The transformation logic is as below:


<?xml version="1.0" encoding="UTF-8" ?>
<?oracle-xsl-mapper
  <!-- SPECIFICATION OF MAP SOURCES AND TARGETS, DO NOT MODIFY. -->
  <mapSources>
    <source type="XSD">
      <schema location="http://localhost:7778/Schemas/Sample.xsd"/>
      <rootElement name="SampleXML" namespace="http://xmlns.oracle.com/
SampleXML"/>
    </source>
  </mapSources>
  <mapTargets>
    <target type="XSD">
      <schema location="
http://localhost:7778/Schemas/Sample.xsd"/>
      <rootElement name="
SampleXML" namespace="http://xmlns.oracle.com/SampleXML"/>
    </target>
  </mapTargets>
  <!-- GENERATED BY ORACLE XSL MAPPER 10.1.3.4.0(build 080718.0645) AT [THU SEP 24 15:16:11 EEST 2009]. -->
?>
<xsl:stylesheet version="1.0"
                xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:hwf="http://xmlns.oracle.com/bpel/workflow/xpath"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                exclude-result-prefixes="xsl xsd bpws hwf">
    <xsl:template match="/">
        <EmployeeListSorted>
            <xsl:for-each select="/EmployeeList/Employee[not(EmpId=following::EmpId)]">
                <xsl:sort select="./EmpId" order="ascending"/>
                <Employee>
                    <xsl:copy-of select="./Name"/>
                    <xsl:copy-of select="./EmpId"/>
                </Employee>
            </xsl:for-each>
        </EmployeeListSorted>
    </xsl:template>   
</xsl:stylesheet>



The preceding-sibling grouping technique did not work as because your nodes are not siblings of each other and because it only works where the grouping key is the string-value of the node, not where it is some other function of the node (here, its name).

Peace !

Cheers,
- AR

Monday, July 12, 2010

Deploying Oracle BRM JCA Adapter for Oracle AIA

This particular post would be useful for those working on Oracle SOA Suite 10g and having the stack Siebel, AIA and BRM. In the stack where there is Siebel, AIA and BRM, AIA invokes BRM through the JCA Adapter. This JCA Adapter is provided by the BRM Team. The JCA Adapter is responsible for converting the xml given by AIA to the input flist of BRM. The JCA Adapter also does a basic field level validation of the input xml with the opcode being called. This JCA Adapter is deployed in the middleware layer, using the Oracle SOA Suite’s EM Console.

Please do the following to deploy the JCA Adapter:

  1. Modify the application.xml: Go to $ORACLE_HOME/j2ee/$OC4J_CONTAINER/config and Modify the imported-shared-libraries to contain the oracle.bpel.common library also. Modify the imported-shared-libraries to contain the below entry:

    <import-shared-library name="oracle.bpel.common" />

    The imported-shared-libraries after the change will look as below:

    <imported-shared-libraries>
    <import-shared-library name="adf.oracle.domain" />
    <import-shared-library name="oracle.bpel.common" />
    </imported-shared-libraries>


  2. Deploy the JCA Adapter: Get the latest JCA Adapter from BRM, go to EM Console and navigate to oc4j_soa. Go to Applications tab, select Standalone Resource Adapters from the View drop down option and Choose Deploy, to deploy the BRM JCA Adapter. While deploying if the JCA Adapter is placed on the server directly, choose the option of location as Location on Server or if the JCA Adapter is present in the workstation, choose the option of browsing the file from the workstation. Choose Automatically create a new deployment plan option (Step 1/3), choose next, give a name for the Resource Adapter (Step 2/3) and make no changes in the Deployment Settings tab (Step 3/3). Click Return on successful deployment of the adapter.
  3. Create Connection Factory: Click on the JCA Adapter that was just deployed from Standalone Resource Adapters. Click on Connection Factories tab (need to create a Shared Connection Pool before we define the Connection Factory). So, click on Create option under Shared Connection Pools to create one. Create a connection factory using the shared connection pool that has been created. In JNDI Location, issue eis/BRM, choose Use Shared Connection Pool under Connection Pooling and change the Connection String to ip $BRMIPAddress $BRMPort, Username and Password of the BRM user that SOA Suite will use.
  4. Restart JCA Adapter: Stop the JCA Adapter by navigating to Standalone Resource Adapters and choosing the adapter.  Once stopped, start the JCA adapter from the same location.

Peace !

Cheers,
- AR
Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License