Thursday, September 26, 2013

XSLT : Filter Child node based on Parent node value

This blog post will help you to filter child node elements based on parent node values in XSL transformation.

Given solution will help you to create master and detail relationship, when you are getting parent and child data from different sources.

Simple steps:

  • Create a variable to hold a key value from parent node to identify child nodes.(Note: The variable declared immediately after for-each tag in given sample XSLT)
  • Refer that variable value in child node to filter the results.

Sample XSLT with solution to filter employees node results by department ID:

<?xml version="1.0" encoding="UTF-8" ?>
<?oracle-xsl-mapper 
  <mapSources>
<!-- SOURCE 1 - Departments Data. -->
    <source type="XSD">
      <schema location="../xsd/DEPARTMENTS.xsd"/>
      <rootElement name="OutputParameters" namespace="http://xmlns.oracle.com/pcbpel/adapter/db/HR/GET_DEPT/"/>
    </source>
<!-- SOURCE 2 - Employees Data. -->
    <source type="XSD">
      <schema location="../xsd/EMPLOYEES.xsd"/>
      <rootElement name="OutputParameters" namespace="http://xmlns.oracle.com/pcbpel/adapter/db/HR/GET_EMPLOYEES/"/>
      <param name="varGetEmployeesDBAdapterOutput.OutputParameters" />
    </source>
  </mapSources>
  <mapTargets>
    <target type="XSD">
      <schema location="../xsd/QueryDept.xsd"/>
      <rootElement name="QueryEmpResponse" namespace="http://www.lkakarla.com/2013/09/QueryEmp"/>
    </target>
  </mapTargets>
?>
<xsl:stylesheet version="1.0"
                xmlns:db="http://xmlns.oracle.com/pcbpel/adapter/db/HR/GET_DEPT/"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:tns="http://www.lkakarla.com/2013/09/QueryEmp"
                xmlns:ns1="http://xmlns.oracle.com/pcbpel/adapter/db/HR/GET_EMPLOYEES/"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                exclude-result-prefixes="xsi xsl db ns0 ns1 xsd tns xp20 bpws aia mhdr bpel oraext dvm hwf med ids bpm xdk xref bpmn ora socket ldap">
  <xsl:param name="varGetEmployeesDBAdapterOutput.OutputParameters"/>
  <xsl:template match="/">
    <tns:QueryEmpResponse>
      <tns:ResponseBody>
        <xsl:for-each select="/db:OutputParameters/db:OUT_DEPT_CUR/db:OUT_DEPT_CUR_Row">
          <xsl:variable name="DeptID" select="db:DEPT_ID"/>
          <tns:Identity>
              <tns:DepartmentID>
                <xsl:value-of select="db:DEPT_ID"/>
              </tns:DepartmentID>
              <tns:DepartmentName>
                <xsl:value-of select="db:DEPT_NAME"/>
              </tns:DepartmentName>
             <tns:Employees>
              <xsl:for-each select="$varGetEmployeesDBAdapterOutput.OutputParameters/ns1:OutputParameters/ns1:OUT_EMPLOYEE_CUR/ns1:OUT_EMPLOYEE_Row[(ns1:DEPT_ID = $DeptID)]">
                <tns:Employee>
                  <tns:EmployeeID>
                    <xsl:value-of select="ns1:EMPLOYEE_ID"/>
                  </tns:EmployeeID>
                  <tns:EmployeeName>
                    <xsl:value-of select="ns1:EMPLOYEE_NAME"/>
                  </tns:EmployeeName>
                </tns:Employee>
              </xsl:for-each>
            </tns:Employees>
          </tns:Identity>
        </xsl:for-each>
      </tns:ResponseBody>
    </tns:QueryEmpResponse>
  </xsl:template>
</xsl:stylesheet>

1 comment:

Provide your thoughts !