I've completed my solution to the problem of compiling user supplied xpath expressions and capturing syntax errors all from within an XSL stylesheet.  Here's how I solved it.

First I wrote this java class to do the compilation and capture an error if it exists:

public class MyXPath {
    public static String getSyntaxError(String path) {
        XPath xpath = XPathFactory.newInstance().newXPath();
        NamespaceContext context = new MyNamespaceContext();
        XPathFunctionResolver resolver = new MyFunctionResolver();
        try {
        catch(XPathException e) {
            String message = e.getMessage();
            if( message == null ) message = e.getCause().getMessage();
            return message;
        return "";
    private static class MyNamespaceContext implements NamespaceContext {
        public String getNamespaceURI(String prefix) {
            if (prefix == null) throw new NullPointerException("Null prefix");
            else if ("itg".equals(prefix)) return "http://www.itg.com";
            return XMLConstants.NULL_NS_URI;
        public String getPrefix(String uri) { throw new UnsupportedOperationException(); }
        public Iterator getPrefixes(String uri) { throw new UnsupportedOperationException(); }
    private static class MyFunctionResolver implements XPathFunctionResolver {
        public XPathFunction resolveFunction(QName fname, int arity) {
           if (fname == null) throw new NullPointerException("The function name cannot be null.");
           if (fname.equals(new QName("http://www.itg.com", "fts", "itg")))
              return new XPathFunction() { public Object evaluate(java.util.List args) { return null; } };
           else return null;

Next I added the extension to my stylesheet:

    extension-element-prefixes="xsl saxon MyXPath"

...and then I used the function:

<xsl:template match="@path">
    <xsl:variable name="error" select="MyXPath:getSyntaxError(.)"/>
    <xsl:if test="string($error)">
        <xsl:attribute name="invalid_path" select="$error"/>
    <xsl:copy-of select="."/>

and so a document containing user supplied xpath expressions are marked with invalid attributes signifying syntax errors that may exist.  Acceptance of the custom function itg:fts() in the expression is also allowed.  User's are given a chance to fix the errors before the xpath expressions are actually used to perform a query.

Todd Gochenour