SAXONICA

Saxon Documentation
Full Contents
About Saxon
Changes in this Release
Conditions of Use
Using XSLT 2.0
Using XQuery
Handling Source Documents
XML Schema Processing
The XPath API
Saxon on .NET
Extensibility
| Introduction
» | Writing extension functions in Java
| Converting Arguments to Java Extension Functions
| Converting the Result of a Java Extension Function
| Writing extension instructions
| Writing input filters
| Writing output filters
| Implementing a collating sequence
| Localizing numbers and dates
| Adding an output encoding
| Writing a URI Resolver for Input Files
| Writing a URI Resolver for Output Files
Saxon Extensions
Sample Saxon Applications
The Saxon SQL Extension
XSLT Elements
XPath 2.0 Expression Syntax
Function Library
Standards Conformance

# Calling Static Methods in a Java Class

Static methods can be called directly. The localname of the function must match the name of a public static method in this class. The names match if they contain the same characters, excluding hyphens and forcing any character that follows a hyphen to upper-case. For example the XPath function call `to-string()` matches the Java method `toString()`; but the function call can also be written as `toString()` if you prefer.

If there are several methods in the class that match the localname, and that have the correct number of arguments, then the system attempts to find the one that is the best fit to the types of the supplied arguments: for example if the call is `f(1,2)` then a method with two `int` arguments will be preferred to one with two `float` arguments. The rules for deciding between methods are quite complex. Essentially, for each candidate method, Saxon calculates the "distance" between the types of the supplied arguments and the Java class of the corresponding method in the method's signature, using a set of tables given below. For example, the distance between the XPath data type `xs:integer` and the Java class `long` is very small, while the distance between an XPath `xs:integer` and a Java `boolean` is much larger. If there is one candidate method where the distances of all arguments are less-than-or-equal-to the distances computed for other candidate methods, and the distance of at least one argument is smaller, then that method is chosen.

If there are several methods with the same name and the correct number of arguments, but none is preferable to the others under these rules, an error is reported: the message indicates that there is more than one method that matches the function call.

This binding is carried out statically, using the static types of the supplied arguments, not the dynamic types obtained when the arguments are evaluated. If there is insufficient static type information to distinguish the candidate methods, an error is reported. You can supply additional type information using the `treat as` expression, or by casting. Often it is enough simply to declare the types of the variables used as arguments to the function call.

For example (in XSLT):

    <xsl:value-of select="math:sqrt($arg)"
       xmlns:math="java:java.lang.Math"/>

This will invoke the static method `java.lang.Math#sqrt()`, applying it to the value of the variable `$arg`, and copying the value of the square root of `$arg` to the result tree.

Similarly (in XQuery):

    <a xmlns:double="java:java.lang.Double"/>
                                  {double:MAX_VALUE()} </a>

This will output the value of the static field `java.lang.Double#MAX_VALUE`. (In practice, it is better to declare the namespace in the query prolog, because it will then not be copied to the result tree.)

A static Java method called as an extension function may have an extra first argument of class `net.sf.saxon.expr.XPathContext`. This argument is not supplied by the calling XPath or XQuery code, but by Saxon itself. The `XPathContext` object provides methods to access many internal Saxon resources, the most useful being `getContextItem()` which returns the context item from the dynamic context. The XPathContext object is available with static or instance-level methods, but not with constructors.

The following example shows a function that obtains the line number of the context node (this is actually a built-in Saxon extension):

        /**
        * Return the line number of the context node.
        */
        public static int lineNumber(XPathContext c) {
            Item item = c.getCurrentIterator().current();
            if (item instanceof NodeInfo) {
                return ((NodeInfo)item).getLineNumber();
            } else {
                return -1;
            }
        }

If this method appears in class `com.example.code.NodeData`, then it can be accessed using the following code in XSLT:

    <xsl:value-of select="nd:line-number()"
        xmlns:nd="java:com.example.code.NodeData"/>

or the following in XQuery:

    <line xmlns:nd="java:com.example.code.NodeData">
        { nd:line-number() }
    </line>

Next