As I'm sure you're aware, XPath 3.0 is still a moveable feast. The syntax for URILiterals has changed to

Q{uri}local

but I'm not sure without checking if Saxon 9.4 implements this change.

But I note that the error message still gives the old syntax.

You seem to be taking a branch were XPath 3.0 syntax is not enabled, and that will depend on how Saxon is invoked.

There's a lot of information in your post, I'll come back to it later today.

Michael Kay
Saxonica


On 08/08/2012 10:21, Ronald van Kuijk wrote:

Hi,

 

First of all, thanks for a great framework/library. Very, very useful. 

 

Last week I tried to replace Saxon-HE 9.2.1.5 in the BetterFORM XForms engine with Saxon 9.3.0.11 with good success. Now, immediately after that, the question came to replace that with the latest 9.4.0.4 version. After making sure everything compiled again, I ran the BetterFORM test and got a lot (25%) failing tests. Luckily, most of the errors were identical.

 

The expanded QName syntax "uri":local is not allowed in this version of XPath/XQuery

 

I found that this message is coming from the ExpressionParser

 

    public void nextToken() throws XPathException {

        try {

            t.next();

            if ((t.currentToken == Token.NAME || t.currentToken == Token.FUNCTION) &&

                    t.currentTokenValue.startsWith("{")) {

                if (allowXPath30Syntax) {

                    t.currentTokenValue = normalizeEQName(t.currentTokenValue);

                } else {

                    throw new XPathException(

                            "The expanded QName syntax \"uri\":local is not allowed in this version of XPath/XQuery");

                }

            }

        } catch (XPathException err) {

            grumble(err.getMessage());

        }

    }

 

An example xpath expression that fails is below where all elements are in the default and EMPTY namespace (xmlns=”” as is common in xforms instances)

 

string(../amount * instance('convTable')/rate[@currency=current()/../currency])

 

When debugging, I found that the “currentTokenValue” of e.g. the amount element is ”{}amount” (without the quotes). When the expression is build, nothing fails but when it is actually evaluated, it fails with the exception above. When I change the xmlns=”” to e.g. xmlns=”bla” I do not get this error anymore and things start working again (to some extend), but that would result in other major changes in all xpath statements).

 

I created a custom build of Saxon-HE with the “if (allowXPath30Syntax)” disabled and then everything starts working again in the default empty namespace. I did not want to set this “allowXPath30Syntax“ to true since it might result in lots of other side effects and/or behavioral issues (not even sure it is allowed in the HE version).

 

One thing I am not sure about if is this only fails if there are functions used that are in the xforms namespace (which is the defaultfunctionnamespace, hence no prefixes). I also noticed is that in the NamePool apidocs a comment was made: “Modified in 9.4 to remove namespace codes.”  So I am not sure if this is a problem in the creating of the name, in the parsing of the expression or that for using 9.4 something has to be changed in the way the api is used.

 

Some more information about the latter:   

-       We do not use the s9api (yet, but I think we cant)

-       We change the default function namespace to the xforms ns

-       We set the ‘backwards compatibility flag’ to true (setting it to false makes no difference)

-       The configuration is ‘basic’ (XPath2) besides custom function libraries being added

-       We use Documents, not Xdm*

 

The two major functions we have that do all this are:

 

    public XPathExpression getXPathExpression(String xpathString, Map prefixMapping, Configuration configuration) throws XPathException {

 

        XPathEvaluator xpe = new XPathEvaluator(configuration);

 

        IndependentContext independentContext = (IndependentContext) xpe.getStaticContext();

        independentContext.setDefaultFunctionNamespace(NamespaceConstants.XFORMS_NS);

        independentContext.setBackwardsCompatibilityMode(true);

 

        for (Iterator it = prefixMapping.entrySet().iterator(); it.hasNext();) {

            Map.Entry entry = (Map.Entry) it.next();

            independentContext.declareNamespace((String) entry.getKey(), (String) entry.getValue());

        }

        independentContext.setFunctionLibrary(fgXFormsFunctionLibrary);

 

 

        XPathExpression exp = xpe.createExpression(xpathString);

        return exp;

    }

 

Which in turn is called from:

 

    public List evaluate(List nodeset, int position, String xpathString, Map prefixMapping, XPathFunctionContext functionContext)

        throws XFormsException {

        if (nodeset != null && nodeset.size() < position) {

            return Collections.EMPTY_LIST;

        }

 

 

        try {

            final XPathExpression exp = getXPathExpression(xpathString, prefixMapping, functionContext != null?functionContext.getXFormsElement().getContainerObject().getConfiguration():XPathCache.kCONFIG);

            final XPathDynamicContext context = exp.createDynamicContext((Item) nodeset.get(position - 1));

            ListSequenceIterator nodesetIt = new ListSequenceIterator(nodeset, position);

            nodesetIt.next();

                    ((XPathContextMajor)context.getXPathContextObject()).setCurrentIterator(nodesetIt);

            context.getXPathContextObject().getController().setUserData(XFormsProcessorImpl.class.toString(), XPathFunctionContext.class.toString(), functionContext);

 

            SequenceIterator it = exp.iterate(context);

 

            int nrOfEntries;

            if ((it.getProperties() & SequenceIterator.LAST_POSITION_FINDER) != 0) {

                nrOfEntries = ((LastPositionFinder) it).getLength();

            } else {

                nrOfEntries = -1;

            }

 

            if (nrOfEntries == 1) {

                return Collections.singletonList(it.next());

            }

 

            final List result = new ArrayList(nrOfEntries > 0 ? nrOfEntries : 20);

            for (Object item = it.next(); item != null; item = it.next()) {

                result.add(item);

            }

 

            return result;

 

        } catch (XPathException e) {

             if (e.getCause() instanceof XFormsException) {

                   throw (XFormsException)e.getCause();

             }

            throw new XFormsException(e.getMessage(), e);

        }

 

    }

 

Thanks in advance,

 

Ronald van Kuijk



------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/


_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
saxon-help@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/saxon-help