Saturday, November 27, 2010

Extending XSLT with Java Static Methods

Now, this time my blog post is about ; using Java to extend XSLT functionality to get more out of XSLT. I'm going to start-off with simple way of extending XSLT by using Static Java Methods. These methods can be invoked from your XSLT Templates to get your complex calculations and transformations done in Java that cannot be done with XSLT or which is more difficult to read/maintain in XSLT.

Ok, we will get into the sample now. I have a sample XML file that has Student Records (First Name, Second Name, Department Id and Grade) - My simple objective is to generate a HTML Page with this records that shows the table of Student names, their department name and grade. Huh!... My XML is having only the Department Id and I need the department name in my HTML. Well, I can write a xslt choose block to select the department name when I'm given department id, but whenever I have changes in this mapping I have to modify my XSLT and also this is not going to be the primary data source as the university will have its own database that has Department details. So, I'm going to query the DB and use the name in my XSLT. Well, though I can do that; I don't want to complicate my example - I have a flat Java properties file that will have the DepartmentId=DepartmentName mapping and I'll use it in my XSLT invoked Java methods. The same way, grade name is also fetched from a properties file.


StudentRecords.xml
<?xml version="1.0" encoding="UTF-8"?>
<Students>
    <Student>
        <FirstName>First</FirstName>
        <SecondName>Name</SecondName>
        <DeptId>1</DeptId>
        <Grade>A</Grade>
    </Student>
    <Student>
        <FirstName>Second</FirstName>
        <SecondName>Name</SecondName>
        <DeptId>3</DeptId>
        <Grade>B</Grade>
    </Student>
    <Student>
        <FirstName>Third</FirstName>
        <SecondName>Name</SecondName>
        <DeptId>2</DeptId>
        <Grade>C</Grade>
    </Student>
    <Student>
        <FirstName>Fourth</FirstName>
        <SecondName>Name</SecondName>
        <DeptId>4</DeptId>
        <Grade>D</Grade>
    </Student>
    <Student>
        <FirstName>Fifth</FirstName>
        <SecondName>Name</SecondName>
        <DeptId>5</DeptId>
        <Grade>E</Grade>
    </Student>
</Students>



DeptMapping.properties
1=Maths
2=Physics
3=Chemistry
4=Biology



GradeMapping.properties
A=Outstanding
B=Good
C=Average
D=Poor



The output HTML page we will get is the following


<html xmlns:jClass="xalan://ExtendedXSLT" xmlns:xalan="http://xml.apache.org/xalan" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <head>
        <title>Students List</title>
    </head>
    <body>
        <h1>Students List</h1>
        <table border="1">
            <tbody>
                <tr>
                    <th>Name</th>
                    <th>Department Id</th>
                    <th>Department Name</th>
                    <th>Grade Id</th>
                    <th>Grade Name</th>
                </tr>
                <tr>
                    <td>First Name</td>
                    <td>1</td>
                    <td>Maths</td>
                    <td>A</td>
                    <td>Outstanding</td>
                </tr>
                <tr>
                    <td>Second Name</td>
                    <td>3</td>
                    <td>Chemistry</td>
                    <td>B</td>
                    <td>Good</td>
                </tr>
                <tr>
                    <td>Third Name</td>
                    <td>2</td>
                    <td>Physics</td>
                    <td>C</td>
                    <td>Average</td>
                </tr>
                <tr>
                    <td>Fourth Name</td>
                    <td>4</td>
                    <td>Biology</td>
                    <td>D</td>
                    <td>Poor</td>
                </tr>
                <tr>
                    <td>Fifth Name</td>
                    <td>5</td>
                    <td>NotFound</td>
                    <td>E</td>
                    <td>NotFound</td>
                </tr>
            </tbody>
        </table>
    </body>
</html>


You can download all the files that are discussed here along with the Java Source Code and XSLT from the following URL - http://www.filefactory.com/file/b4735a0/n/ExtendedXSLT.zip

The Java Class ExtendedXSLT does nothing more than loading the Department and Grade Properties, setting the System Property to use Xalan Transformer and transforming the XML using our XSLT. But, it has two public static methods that are not used anywhere in the main method. But, these methods are used in XSLT to get the mapping from DepartmentId and Grade Id. The magic is done by adding the xml namespace declaration in XSLT that xalan is the prefix for xalan's Namespace ( http://xml.apache.org/xalan ) and jClass is the prefix that will refer to our ExtendedXSLT Class. This is done by using the function in xalan namespace. You can see that our XSLT will have a prefix defined called jClass that is mapped to "xalan://ExtendedXSLT". This statement helps us to invoke the methods in ExtendedXSLT class by using the jClass prefix. You can also refer to more than one class by specifying them in the same prefix separated by comma. Xalan will take care of locating the method.

Though this method is simple to extend the XSLT, this can be very useful when you want to do complex calculations, type conversions, external entity calls, etc. Hope, this will be useful for few people out there.

No comments:

Post a Comment