2009/02/18

XSLT Unit Testing

I like test driven development and automatic testing, so also for my XSLT code.
I wanted to do this also within Oracle SOA Suite. Unfortunately this comes not out-of-the-box from the SOA Suite, so i searched the Net.
Eventually i came to XMLUnit 1.2, whcih is an extension of JUnit (version 3.8.2).
This framework contains some extension functions especially for XML, like transformations.

Configuration
First you have to configure XMLUnit to use the Oracle XSLT classes:
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "oracle.xml.jaxp.JXDocumentBuilderFactory");
System.setProperty("javax.xml.parsers.SAXParserFactory", "oracle.xml.jaxp.JXSAXParserFactory");
System.setProperty("javax.xml.transform.TransformerFactory", "oracle.xml.jaxp.JXSAXTransformerFactory");

Implementing a test case
Extend from XMLTestCase:
public class MyTestCase extends XMLTestCase

Configure namespaces (this can be done within the setup() method:
    protected void setUp() {
        HashMap m = new HashMap();
        m.put("msg", "http://www.example.nl/Message/v1.0");
        m.put("org", "http://www.example.nl/Organisation/v1.0");
        ctx = new SimpleNamespaceContext(m);
        XMLUnit.setXpathNamespaceContext(ctx);

Do a transformation on test data:
    public static Document transform(String input, String xsl) throws Exception{
        System.out.println("Input: " + input);
        System.out.println("Xsl: " + xsl);
        File inputStream = new File(input);
        File myStyleSheet = new File(xsl);
        Transform myTransformation = new Transform(
            new StreamSource(inputStream), new StreamSource(myStyleSheet));
        String result = myTransformation.getResultString();
        Document doc = myTransformation.getResultDocument();
        
        System.out.println(result);
        return doc;
    }

Test the outcome with asserts:
assertXpathEvaluatesTo("000001","/msg:Message/org:Employment/org:ID", doc);
"/msg:CizMessage/msg:Body/org:Employment/org:StartDate", doc);

Put into JUnit testsuite (Example AllTests class):
    public static TestSuite suite( ) {
        TestSuite suite= new TestSuite("All JUnit Tests");
        suite.addTestSuite(unittest.MyTestCase.class);
        return suite;
    }
    TestRunner.run(tests.suite());

Be sure to include the jars (JDeveloper):
%ORACLE_SOA%\integration\esb\lib\bpm-services.jar
%ORACLE_SOA%\integration\esb\lib\commons-logging.jar
%ORACLE_SOA%\integration\esb\lib\orabpel.jar
%ORACLE_SOA%\integration\esb\lib\xmlparserv2.jar
%ORACLE_SOA%\integration\esb\lib\xsu12.jar
%JUNIT%\junit.jar
%XMLUnit%\lib\xmlunit-1.2.jar

You can also run the tests within Ant (I used JDeveloper 10.1.3.4 included Ant)
Build.xml file:

Waarbij ${testsuite.class}=AllTests

2009/02/05

Oracle SOA Suite: Adding a custom XSL Function to ESB

Sometimes you need a function within the XSLT that is not available within the standard XPath/XSLT functions or within the Oracle extensions, so you have to make an extension. This post explains how this can be done (within 10.1.3.x).

1) Create Java class that implements the extension function. You must inherit from IXPathFunction.
Note: To be able to test your function within JDeveloper you have to add the Orabpel.jar and Orabpel-common.jar libraries.

2) To be able to "see" the function within JDeveloper to have to create a extension function config file:


Within JDeveloper go to "Tools - Preferences" and select XSL Maps. Browse to the config file and restart JDeveloper afterwards.
Within the component view you can see the extension function:

3) Use within the XSL file.
Add the namespace of the extension function:
xmlns:ext="http://www.oracle.com/XSL/Transform/java/.CizBase64Encoder"

And then use with the XSL code:

4) Add to SOA Suite runtime.
To be able to use it you should copy the classes to:
%ORACLE_SOA%\bpel\system\classes
Note: Do not forget package directories.

And you are Done!