Home | Ciber
Knowledge page of Ciber Netherlands

Creating XSLT-extensions with SAXON

Suppose you want to do some heavy lifting with xslt (2.0) but xslt provides no  out-of-the-box functions for your problem.  In that case you can create your own xslt extensions. 

Below you find a small demo how to accomplish this.

Use case:  You want to check if a file exists on the file system with xslt.

1) Create a java class which provides a STATIC  method returning a boolean if the file exists.

package com.ciber.cocoonDemo;

import java.io.File;

public class FileUtils {

public static boolean fileExists(String fileName) {

            File file = new File(fileName);

return file.exists();

      }

}

 

To call static methods from within xslt is very easy. 

In the stylesheet below, there are a few things to notice.  I chose to create a custom xslt function ‘fileExists’ which MUST be bound to a namespace. 

In my case I declared a namespace ‘http://www.ciber.nl‘  which I bound to the prefix ‘ciber’.

Within that custom function,  I bound  the prefix ‘fileUtils’ to the java class ‘com.ciber.cocoonDemo.FileUtils’.   The custom function takes one parameter ‘_filename’ which passes this parameter when invoking the fileExists method.

 

Test.xslt

<?xml version="1.0" encoding="UTF-8"?>

<!–

Author: Robby Pelssers

Unit test for xslt extension  FileExist

–>

<xsl:stylesheet version="2.0"

  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

  xmlns:xs="http://www.w3.org/2001/XMLSchema"

  xmlns:fn="http://www.w3.org/2005/xpath-functions"

  xmlns:ciber="http://www.ciber.nl">

  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

  <xsl:template match="/">

    <test>

      <xsl:for-each select="//file">

        <file name="{@name}">

          <exists><xsl:value-of select="ciber:fileExists(@name)"/></exists>

        </file>

      </xsl:for-each>

    </test>

  </xsl:template>

  <xsl:function name="ciber:fileExists" as="xs:boolean" xmlns:fileUtils="java:com.ciber.cocoonDemo.FileUtils">

    <xsl:param name="_filename" as="xs:string" />

    <xsl:sequence select="fileUtils:fileExists($_filename)"/>

  </xsl:function>

  </xsl:stylesheet>

 

Input.xml

 

<?xml version="1.0" encoding="UTF-8"?>

<test>

  <file name="d:/somefile.xml"/>

  <file name="d:/output.xml"/> 

</test>

 

Output after transformation

 

<test>

  <file name="d:/somefile.xml">

    <exists>true</exists>

  </file>

  <file name="d:/output.xml">

    <exists>false</exists>

  </file>

</test>

 

Robby Pelssers

No comments yet. Be the first.

Leave a reply