WAS v8.5 > Develop applications > XML applications > Use the XML API to perform operations > Use external variables and functions > Use external functions

Use external functions with XSLT

When using an XSLT stylesheet that uses external functions, declare the function signatures using an XStaticContext instance and supply (or bind) a Java implementation for each function using an XDynamicContext instance.

  1. When preparing an XSLT stylesheet that uses external functions, declare the function signatures using an XStaticContext instance.

    The XStaticContext interface has two declareFunction methods that each have three parameters—one for the name, one for the return type of the function, and an array for the types of the arguments. The name is always provided as a QName object, but the types can be QNames or XSequenceTypes. The function name, return type, and argument types must uniquely identify the function.

    A stylesheet function could have the same name as an external function. If the stylesheet function has an override attribute with the value of yes, any reference to that function name in the stylesheet is a reference to the stylesheet function; if it has an override attribute with the value of no, it is a reference to the external function.

    XStaticContext declareFunction methods.

    This table explains when to use each form of the declareFunction method.

    Method Signature Purpose
    declareFunction(QName name, QName type, QName[] argTypes) Use when the return value and arguments of the function are all single atomic values

    The type QNames must refer to built-in types or global types declared in a schema that has been registered on the XFactory instance used to create the XStaticContext instance. If a QName refers to a non-atomic type, then the processor will treat it as the type element(*, ns:type), where ns:type is the given QName. The XTypeConstants interface has convenient constants available that provide a QName object for each built-in type.

    declareFunction(QName name, XSequenceType type, XSequenceType[] argTypes) Use when any of the arguments or the return value of the function is a node or a sequence of atomic values or nodes

    The following stylesheet uses an external function referred to by the QName ext:pow.

    <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:ext="http://www.example.com/functions"
                    version="2.0"> 
        <xsl:output method="text"/> 
        <xsl:template match="polynomial">         <xsl:variable name="p" select="."/> 
            <xsl:for-each select="1 to 5">             <xsl:text>x = </xsl:text>             <xsl:value-of select="."/>             <xsl:text>; </xsl:text>             <xsl:value-of select="for $t in $p/term return concat($t/@coefficient, 'x^', $t/@power)"
                              separator=" + "/>             <xsl:text> = </xsl:text>             <xsl:value-of select="sum($p/term/(ext:pow(current(), @power) * @coefficient))"/>             <xsl:text>&#xA;</xsl:text>         </xsl:for-each>     </xsl:template> 
    </xsl:stylesheet>

    Assuming the stylesheet above is available using the xsltSource Source object, the code below prepares the stylesheet.

    // Create the factory
    XFactory factory = XFactory.newInstance();
    
    // Create a new static context XStaticContext staticContext = factory.newStaticContext();
    
    // Declare a namespace for the function staticContext.declareNamespace("ext", "http://www.example.com/functions");
    
    // Create a QName for the name of the function QName methodQName = new QName("http://www.example.com/functions", "pow");
    
    // Declare the function on the static context staticContext.declareFunction(methodQName, XTypeConstants.DOUBLE_QNAME, new QName[]{XTypeConstants.DOUBLE_QNAME, XTypeConstants.DOUBLE_QNAME});
    
    // Create an XSLT executable for the stylesheet
    XSLTExecutable executable = factory.prepareXSLT(xsltSource, staticContext);
  2. To execute an XSLT stylesheet that uses external functions, supply (or bind) the Java methods that implement the functions using an XDynamicContext instance.

    Use Java reflection to obtain a java.lang.reflect.Method object for the function. If the method is an instance method, an instance object is required when binding this function.

    An error is raised if we do not supply a Java method for a function used when executing the XSLTstylesheet.

    The XDynamicContext has two bindFunction methods. Each requires a QName object corresponding to the name of the function and a Method object identifying the Java method that will provide the implementation for the function.

    XDynamicContext bindFunction methods.

    This table explains when to use each form of the XDynamicContext bindFunction methods.

    Method Name Purpose
    bindFunction(QName qname, Method method) Use when binding a static method
    bindFunction(QName qname, Method method, Object instanceObject) Use when binding an instance method

    The following example executes the XSLT stylesheet prepared in the first example, first binding a method for the function it uses. In this example, the static pow(double a, double b) method of the java.lang.Math class is used to provide the implementation for the external function.

    // Create a new dynamic context XDynamicContext dynamicContext = factory.newDynamicContext();
    
    // Retrieve the java.lang.reflect.Method object for this function Method method = Math.class.getMethod("pow", Double.TYPE, Double.TYPE);
    
    // Bind the function to the dynamic context dynamicContext.bindFunction(methodQName, method);
    
    // Create an XML input document
    String xml = "<polynomial>" +
    "<term power='2' coefficient='3'/>" +
    "<term power='1' coefficient='-2'/>" +
    "<term power='0' coefficient='1'/>" +
    "</polynomial>";
    StreamSource source = new StreamSource(new StringReader(xml));
    
    // Execute the stylesheet
    XSequenceCursor result = executable.execute(source, dynamicContext);
     
    // Serialize the result to System.out result.exportItem(new StreamResult(System.out), executable.getOutputParameters());


Subtopics


Related concepts:

The XFactory class


Related


Use static and dynamic contexts
Use sequence types
Map XML types to Java types
Use stylesheet-declared external functions with XSLT


+

Search Tips   |   Advanced Search