Project

Profile

Help

Use java function in stylesheet with saxon xslt processor

Added by Ming Yu over 12 years ago

Hi,

I've been using Xalan xslt processor before so I'm used to use the java function this way: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="xalan://java.util.Math" version="1.0">

Or any java function I wrote: xmlns:myfn="xalan://com.mycompany.myproduct.Utils

But when I tried to use saxon, from the research I've done, it seems that all I need is this: xmlns:myfnb="java:com.mycompany.myproduct.Utils"

and I should be able to use any methods in Utils class.

But the fact is that, when I tried this with Saxon-HE, I got the following error message:

Error on line 5 of foo.xsl: XTDE1425: Cannot find a matching 0-argument function named {java.util.Math}random(). For diagnostics on calls to Java methods, use the -TJ command line option or set the Configuration property FeatureKeys.TRACE_EXTERNAL_FUNCTIONS in built-in template rule ; SystemID: file:/C:/foo.xsl; Line#: 5; Column#: -1 net.sf.saxon.trans.XPathException: Cannot find a matching 0-argument function named {java.util.Math}random(). For diagnostics on calls to Java methods, use the -TJ command line option or set the Configuration property FeatureKeys.TRACE_EXTERNAL_FUNCTIONS at net.sf.saxon.expr.ErrorExpression.evaluateItem(ErrorExpression.java:66) at net.sf.saxon.expr.ErrorExpression.iterate(ErrorExpression.java:80) ...

My simple foo.xsl is like this:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:math="java.util.Math" version="1.0"> <xsl:template match="doc"> <xsl:value-of select="."/>

<xsl:value-of select="math:random()"/>

</xsl:template> </xsl:stylesheet>

My simple transformer java class is like this:

public static void main(String[] args) {

    File xsltFile = new File("C:/foo.xsl");
    File xmlFile = new File("C:/foo.xml");
    File resultFile = new File("C:/result.xml");

    try {
  
        Source xmlSource = new StreamSource(xmlFile);
        Source xsltSource = new StreamSource(xsltFile);
        
        Processor proc = new Processor(false);
        XsltCompiler comp = proc.newXsltCompiler();
        XsltExecutable exp = comp.compile(xsltSource);
        XdmNode source = proc.newDocumentBuilder().build(xmlSource);
        Serializer out = new Serializer();
        out.setOutputProperty(Serializer.Property.METHOD, "xml");
        out.setOutputProperty(Serializer.Property.INDENT, "yes");
        out.setOutputFile(resultFile);
        XsltTransformer trans = exp.load();
        trans.setInitialContextNode(source);
        trans.setDestination(out);
        QName paramName = new QName("IMBOutgoingBarcode");
        trans.setParameter(paramName, new XdmAtomicValue("45678"));
        trans.transform();
       
    } catch (Exception e ) {
    	e.printStackTrace();
    }

}

I believe that it should be an easy task to perform the java function call. But maybe I haven't found the right documentation to look for.

Thanks for the help.

Ming


Replies (4)

Please register to reply

RE: Use java function in stylesheet with saxon xslt processor - Added by Michael Kay over 12 years ago

Documentation on calling Java from Saxon (XSLT and XQuery) is here:

http://www.saxonica.com/documentation/extensibility/intro.xml

The technique you are referring to is referred to as "reflexive" extension functions, and the important point for you to note is that it isn't supported in Saxon-HE.

Your choices are to get a license for Saxon-PE, or to use the alternative mechanism of "integrated extension functions".

Michael Kay Saxonica

RE: Use java function in stylesheet with saxon xslt processor - Added by Ming Yu over 12 years ago

Thanks for the reply! I really appreciate it.

I found this post which is a question posted two years ago: http://dev.saxonica.com/community/boards/3/topics/1161

I tried to download the saxonb and it seems that the call works fine.

And I did try to download both saxon-ee and saxon-pe jars but both give errors. We are trying out different xslt transformer at this moment for our new project. Our preference is saxon but calling java function is an important part of the project.

Thanks!

Ming

RE: Use java function in stylesheet with saxon xslt processor - Added by Ming Yu over 12 years ago

Sorry it's my bad. I forgot to save the evaluation license file in the same folder as my saxon-ee and saxon-pe jar files.

But it bothers me that, when comparing for the speed (run on my own computer), the order from fastest to slowest is: saxonb, saxon-pe, saxon-ee.

I transformed 27 xml files with my stylesheet: saxonb: 1264 ms saxon-pe: 1756 saxon-ee: 3620.

Is this what's expected?

Thanks a lot!

Ming

RE: Use java function in stylesheet with saxon xslt processor - Added by Michael Kay over 12 years ago

How did you measure the speed? If you were running from the command line, it's probably dominated by Java warm-up time, which increases the more code there is to be loaded (and is highly variable depending on what else is running). Also, small jobs can be dominated by compile time, which takes longer in Saxon-EE because it does more optimization (and byte code generation). But I wouldn't normally expect a big start-up difference between PE and EE even allowing for these factors. Depending on how you plan to be running your workload in live production, a better way of measuring might be to use -repeat:50 on the command line which discounts the effect of Java warm-up by running the same transformation repeatedly.

Michael Kay Saxonica

    (1-4/4)

    Please register to reply