The spec of the document() function in XSLT 2.0 implies that if the URI contains no fragment identifier, the result will always be a document node. Without this rule, it's very hard to achieve repeatability of results (two calls on document() with the same arguments must return the same results).
 
You could write your own extension function to return an element node in the document, or you could copy the subtree and return the copy.
 
Michael Kay
http://www.saxonica.com/


From: saxon-help-admin@lists.sourceforge.net [mailto:saxon-help-admin@lists.sourceforge.net] On Behalf Of Steven Grossman
Sent: 16 May 2006 22:22
To: saxon-help@lists.sourceforge.net
Subject: [saxon] URIResolver returns entire document instead of a subtree

I've implemented a URIResolver that returns subtrees of existing documents.  I've noticed that Saxon is passing the entire document instead of my subtrees.  Here's the source code:
 
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
 
public final class URIResolverProblem {
    private static String XSLT =
            "<xsl:stylesheet version=\"2.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n" +
            "    <xsl:output indent=\"yes\" />\n" +
            "    <xsl:strip-space elements=\"*\"/>\n" +
            "\n" +
            "    <xsl:template match=\"/\">\n" +
            "        <xsl:copy-of select=\"document('any.uri')\"/>\n" +
            "    </xsl:template>\n" +
            "</xsl:stylesheet>";
 
    private static final String XML = "<root><leaf/></root>";
 
    public static void main(String[] args) throws TransformerException, ParserConfigurationException {
        TransformerFactory tfactory = TransformerFactory.newInstance();
        DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        tfactory.setURIResolver(new SampleResolver());
        Templates stylesheet = tfactory.newTemplates(new StreamSource(new StringReader(XSLT)));
        Transformer transformer = stylesheet.newTransformer();
        DOMSource emptySource = new DOMSource(documentBuilder.newDocument());
        transformer.transform(emptySource, new StreamResult(System.out));
    }
 
    private static class SampleResolver implements URIResolver {
        private final DocumentBuilder documentBuilder;
        public SampleResolver() throws ParserConfigurationException {
            this.documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        }
 
        public Source resolve(String href, String base) throws TransformerException {
            // for simplicity, ignoring href
            try {
                Document document = documentBuilder.parse(new InputSource(new StringReader(XML)));
                NodeList childNodes = document.getDocumentElement().getChildNodes();
                for (int i = childNodes.getLength() - 1; i >= 0; i--) {
                    Node childNode = childNodes.item(i);
                    if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                        System.out.println("\nreturning the following node: " + childNode.getNodeName() + "\n");
                        return new DOMSource(childNode);
                    }
                }
            } catch (Exception e) {
                throw new TransformerException(e);
            }
            throw new TransformerException("could not find element");
        }
    }
}
here's the output:
 
returning the following node: leaf
 
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <leaf/>
</root>
 
So, I'm returning a DOMSource consisting of the 'leaf' node, but saxon returns the 'root' node.
 
Any ideas?
 
Steven


Yahoo! Messenger with Voice. PC-to-Phone calls for ridiculously low rates.