Re: [xsl] XSLT functions in XPath

Subject: Re: [xsl] XSLT functions in XPath
From: Victor Toni <xsl-list@xxxxxxxxx>
Date: Tue, 10 Oct 2006 11:03:27 +0200
Michael Kay wrote:
>> I am using the Saxon XPath implementation over DOM to take
>> advantage of the XPAth 2.0.
>> This works really well most of the time (the time when I am
>> not missing anything), however I would like to have access to
>> two more functions which would be really helpful:
>>
>> current()
>> sort()
>>
>> Is it somehow possible to use current() in "normal" XPath, an example:
>>
>> contextA = //@isbn = '1234567'
>> contextB = //author[books/book/@isbn = current() ] using contextA
>
> Sadly, no. But you could switch from XPath to XQuery, which would
> allow you
> to write:
>
> let $current := . return //author[books/book/@isbn = $current]
>
> for $x in expr order by $x/sortkey return $x
>
> For the first one there's also a rather horrible workaround in XPath 2.0:
>
> for $current in . return //author[books/book/@isbn = $current]
>
> But in my view it would be cleaner to bind a variable. It's not difficult:
>
> final String isbn = "01234567890";
> VariableResolver vr = new VariableResolver() {
> public Object resolveVariable(QName variableName) {
> if (variableName.getLocalPart().equals("isbn")) {
> return isbn;
> } else {
> return null;
> }
> }
> };
>
The issue I have here is that the variables would be really variable and
calculated dynamically.
Because I was wondering what types I could store in a variable (and
especially how to do it in a generic way) I wrote this little program
which shows a somehow unexpected behavior, at least as it is described in:

http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/xpath/XPathConstants.html#NODESET

Xerces throws an exception,
Saxon returns an ArrayList (which is more useful, but unexpected
according to the spec )
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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;

public class NodeSetTest {

    public static void main( String [] args ) throws Exception {
        final DocumentBuilderFactory builderFactory =
DocumentBuilderFactory.newInstance();
        final DocumentBuilder builder = builderFactory.newDocumentBuilder();
       
        final Document document = builder.newDocument();
       
        final XPathFactory xpathFactory = XPathFactory.newInstance();
        System.out.println("Factory class: " + xpathFactory.getClass());
       
        final XPath xpath = xpathFactory.newXPath();
       
        final Object nodeset = xpath.evaluate("('a', 'b', 'c')",
document, XPathConstants.NODESET);
        showResult(nodeset);

        final Object string = xpath.evaluate("string('a')", document,
XPathConstants.NODESET);
        showResult(string);
    }

    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