WAS v8.5 > Develop applications > XML applications > Use the XML API to perform operations > Performing basic operations > Overview of the XML API

Relationship of the processor to the JAXP

In most cases, you will need to migrate any of the applications that used the Java API for XML Processing (JAXP) to use the current API.

The XSLT and XPath processing portions of JAXP are defined with reference to XSLT 1.0 and XPath 1.0. JAXP does not have provisions for XSLT 2.0 and XPath 2.0 processing. In particular, there are situations in which an XSLT 2.0 or an XPath 2.0 processor must produce a result that is different from that produced by an XSLT 1.0 or an XPath 1.0 processor given identical input and an identical stylesheet or expression. Therefore, it is not possible to instantiate the current processor using JAXP.

JAXP also does not have support for sequences, XQuery 1.0, or the many current data types available in XSLT 2.0, XPath 2.0, and XQuery 1.0. JAXP also is limited in the forms that input and output can take. All these things make it a poor fit for processing XSLT 2.0 stylesheets as well as XPath 2.0 and XQuery 1.0 expressions.

The following examples demonstrate common migration scenarios and how to write code using the current API that is equivalent to code that you might have written using JAXP.


Processing an XSLT stylesheet using the API

The following example demonstrates how to process an XSLT stylesheet and apply it to some input to produce an instance of the javax.xml.transform.Result interface.

XFactory factory = XFactory.newInstance();
XSLTExecutable style = factory.prepareXSLT(new StreamSource("style.xsl"));style.execute(new StreamSource("input.xml"), new StreamResult(System.out));


Processing an XPath expression using the API

The following example demonstrates how to process an XPath expression and apply it to some input.

XFactory factory = XFactory.newInstance();
XPathExecutable pathExpr = factory.prepareXPath("/doc/child[@id='N1378']");

// Process input from a StreamSource
XSequenceCursor result1 = pathExpr.execute(new StreamSource("input.xml"));

// Process input from a DOM node XSequenceCursor result2 = pathExpr.execute(new DOMSource(node));


Resolve URI references

If we used instances of the JAXP URIResolver interface to resolve references to the XSLT document() function, we can now use the XSourceResolver interface to accomplish the same thing. To resolve references to the document() function or the fn:doc() function, we can set an instance of the XSourceResolver interface on an instance of the XDynamicContext interface; to resolve references to stylesheets imported through xsl:import and xsl:include declarations, we can set an instance of the XSourceResolver interface on an instance of the XStaticContext interface.

The following example shows how you might set up an instance of the XSourceResolver interface that treats input documents as XSLT stylesheets and uses them to generate the input data for reference to the doc or document functions in another XSLT stylesheet.

final XFactory factory = XFactory.newInstance();
XSLTExecutable style = factory.prepareXSLT(new StreamSource("style.xsl"));
XDynamicContext dContext = factory.newDynamicContext();

// Create and set an instance of an anonymous inner class as the // XSourceResolver
dContext.setSourceResolver(new XSourceResolver() {
    // Create an item to use as the initial context node for     // transformations in the getSource method     private XItemView fDummyNode =
        factory.getItemFactory()
            .item(new StreamSource(
                new StringReader("<doc/>")));

    // Resolve URIs by loading the resource as an XSLT stylesheet
    // and evaluating it - return the result as the Source to use     public Source getSource(String href, String base) {
        java.net.URI baseURI;
        try {
            // Get base URI object             baseURI = new java.net.URI(base);
        } catch (java.net.URISyntaxException use) {
            throw new RuntimeException(use);
        }
        // Resolved relative reference against base URI
        String resolvedURI = baseURI.resolve(href).toString();

        // Prepare and execute the stylesheet
        XItemView transformResult =
            factory.prepareXSLT(new StreamSource(resolvedURI))
                .execute(fDummyNode);
        return new XItemSource(transformResult);
    }});

XSequenceCursor result = style.execute(new StreamSource("input.xml"), dContext);


Define extension functions and external functions

Using JAXP for XPath expression evaluation, you could register an instance of the XPathFunctionResolver interface to supply the implementations of extension functions that your XPath expressions might call. The XSLT portion of JAXP does not have an equivalent mechanism.

With the current API, we can declare extension functions on an instance of the XStaticContext interface, specifying the expected types of the arguments and the expected type of the result of calling the function, and we can register the implementations of extension functions on an instance of the XDynamicContext interface. Your XSLT stylesheet and XPath and XQuery expressions can call any extension functions that you register.


Set the values of stylesheet parameters and external variables

Using JAXP, you could supply the initial values of stylesheet parameters by calling the Transformer.setParameter method and you could supply the values of variables for XPath expressions by supplying an instance of the XPathVariableResolver interface. Using the API, we can declare variables using the declareVariable() methods of the XStaticContext interface, specifying a variable name and the expected type of the variable. We can supply the values of stylesheet parameters, XPath variables, and XQuery external variables through one of the bind() methods of the XDynamicContext interface.

The following example shows how you might use a variable in an XPath expression to look up product entries in a catalog based on the product identifier.

XFactory factory = XFactory.newInstance();
XStaticContext sContext = factory.newStaticContext();

// Declare the XPath variable "query-id" in the static context QName queryIdVar = new QName("query-id");
sContext.declareVariable(queryIdVar, XTypeConstants.STRING_QNAME);

// Prepare the XPath expression
XItemFactory itemFactory = factory.getItemFactory();
XPathExecutable expr =
    factory.prepareXPath("/catalog/product[id eq $query-id]", sContext);

XItemView catalog = itemFactory.item(new StreamSource("catalog.xml"));
XDynamicContext dContext = factory.newDynamicContext();

// Set the value of the "query-id" variable, and evaluate the // expression with that variable value dContext.bind(queryIdVar, "ID43785");
XSequenceCursor product1 = expr.execute(catalog, dContext);

// Set the value of the "query-id" variable, and evaluate the // expression with the new variable value dContext.bind(queryIdVar, "ID18574");
XSequenceCursor product2 = expr.execute(catalog, dContext);


Identity transformation

Another operation that is frequently used in JAXP is the identity transformation. This is a convenient way of transforming data from one form to another—for example, serializing a DOM tree, or producing a DOM tree from SAX events. It is possible to perform identity transformations using the API. See Performing basic XSLT operations for an example.


Prepare-time and execution-time configuration

In JAXP you supply much of the runtime configuration information for XSLT stylesheets – the values of stylesheet parameters, URIResolvers, and so on—directly on the objects used to perform transformations – instances of the Transformer interface and the TransformerHandler interface. Similarly, you supply configuration information for the preparation of stylesheets and XPath expressions directly on instances of the TransformerFactory and XPathFactory classes in JAXP.

With the API, we can supply configuration information needed at the time a stylesheet or an expression is prepared—namespace bindings, the types of external functions or variables, and so on—using an instance of the XStaticContext interface. Similarly, we can provide any configuration information needed to evaluate a stylesheet or expression—the values of variables, settings of output parameters, and so on—on an instance of the XDynamicContext interface, which we can pass as an argument to the execute methods of the XExecutable interface and its subinterfaces.

This separation of the configuration information into a separate object makes the API more thread safe. Your application can use the same instance of the XExecutable interface on different threads without any synchronization. This stands in contrast to JAXP, where instances of the Transformer, TransformerHandler and XPathExpression interfaces are not thread safe; every thread that uses them has to synchronize access to shared instances of those objects or create distinct copies specific to each thread.


Handling errors

In JAXP, you could supply an instance of the ErrorHandler interface to control how the processor should respond to errors. In the API, we can achieve this by supplying an instance of the XMessageHandler interface on an instance of the XStaticContext interface for preparation-time errors or the XDynamicContext interface for execution-time errors.


Related


View the results
Serializing the results
Use a source resolver at prepare time
Use a source resolver at execution time
Use a result resolver at execution time
Use external functions
Use external variables
Performing basic XSLT operations
Performing basic XPath operations
Performing basic XQuery operations
Manage exceptions
Use a message handler


+

Search Tips   |   Advanced Search