Re: [xsl] XSLT functions in XPath

Subject: Re: [xsl] XSLT functions in XPath
From: Victor Toni <xsl-list@xxxxxxxxx>
Date: Tue, 10 Oct 2006 14:41:19 +0200
Michael Kay wrote:
>> http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/xpath/XPathC
>> onstants.html#NODESET
>>
>> Xerces throws an exception,
>> Saxon returns an ArrayList (which is more useful, but
>> unexpected according to the spec )
>
> When implementing the JAXP XPath API I had to make decisions about how to
> extend it to support XPath 2.0, since as written it's really designed for
> XPath 1.0. Also, it's primarily focused on supporting access to the DOM. I
> decided (rightly or wrongly) that it made sense always to return the
> results
> as a List, rather than special-casing the situation where the result is a
> sequence of DOM nodes and using a DOM NodeList for that special case.

That's fine with me, but it seems that I cannot reuse the result.
Trying to be smart I tried to abstract the implementation away by using
pure XPath to get the size of the resulting NodeList (or whatever), but
Saxon throws an Exception with this example because it doesn't know
about the DOM. (Xalan's XPath throws an exception too but of another
type, it expects the result to have a root).

My main issue is that all the features I know from XSL seem to exist
only as less powerful versions in XPath.

/////////////////////////////////////////
Exception in thread "main" javax.xml.xpath.XPathExpressionException:
Cannot locate an object model implementation for nodes of class
net.sf.saxon.dom.DOMNodeList
    at
net.sf.saxon.xpath.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:229)
    at net.sf.saxon.xpath.XPathEvaluator.evaluate(XPathEvaluator.java:335)
    at test.SaxonTest.main(SaxonTest.java:56)


/////////////////////////////////////////
package test;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class SaxonTest {

    public static void main( String [] args ) throws Exception {
        System.setProperty("jaxp.debug", "true");

        final DocumentBuilderFactory builderFactory =
DocumentBuilderFactory.newInstance();
        final DocumentBuilder builder = builderFactory.newDocumentBuilder();
        
        final Document document = builder.newDocument();
        final Element root = document.createElement("root");
        root.appendChild(document.createElement("a"));
        root.appendChild(document.createElement("b"));
        root.appendChild(document.createElement("c"));
        root.appendChild(document.createElement("d"));
        root.appendChild(document.createElement("e"));
        
        document.appendChild(root);

        final XPathFactory xpathFactory = XPathFactory.newInstance();
        System.out.println("Factory class: " + xpathFactory.getClass());
        
        final XPath xpath = xpathFactory.newXPath();
        
        Object childNodes = document.getDocumentElement().getChildNodes();
        showResult(childNodes);

        Object count = xpath.evaluate("count(*)", childNodes,
XPathConstants.NUMBER);
        showResult(count);
        System.out.println("Nodes found: " + count);

        final Object nodes = xpath.evaluate("/root/*", document,
XPathConstants.NODESET);
        showResult(nodes);

        count = xpath.evaluate("count(*)", nodes, XPathConstants.NUMBER);
        showResult(count);
        System.out.println("Nodes found: " + count);
    }

    private static void showResult( final Object result ) {
        if(null == result) {
            System.out.println("Null result!");
        } else {
            System.out.println("Result class: " + result.getClass());
        }
    }

}

Current Thread