0
votes

I am not a XQuery expert. Jut know enough to get by. Recently I had migrated my very Xquery execution code from Saxon 8.4 to 9.9.1.2. So I did some changes in the way the XQ files are executed. The code is error free but during runtime, I get an exception:

java.lang.IllegalArgumentException: Supplied node must be built using the same or a compatible Configuration

The code that I modified to run the XQ files looks like this:

// Prepare the environment for Saxon
        SaxonErrorListener listener = new SaxonErrorListener();
        listener.setLogger(new StandardLogger(new PrintStream(errors, true, "UTF-8")));
        getSaxonConfig().setErrorListener(listener);
        StaticQueryContext staticContext = new StaticQueryContext(getSaxonConfig());
        Configuration configuration = new Configuration();

        staticContext.setBaseURI("");

        // Set up the dynamic context
        DynamicQueryContext dynamicContext = new DynamicQueryContext(getSaxonConfig());

        if ((xmlData != null) && (xmlData.length() > 0)) {
            dynamicContext.setContextItem(configuration.buildDocumentTree(new StreamSource(new StringReader(xmlData))).getRootNode());
        }             

        // If required use a (URI) uriResolver to handle xquery "doc" functions and module imports
        if (uriResolver != null) {
            dynamicContext.setURIResolver(uriResolver);
            staticContext.setModuleURIResolver(uriResolver);
        }

        // If any external variables required, add them to the dynamic context
        if (getExternalVariables().size() > 0) {

            for (String varname : getExternalVariables().keySet()) {

                StructuredQName structuredQName = new StructuredQName("", "", varname);
                ObjectValue<Object> objectValue = new ObjectValue<Object>(getExternalVariables().get(varname));
                dynamicContext.setParameter(structuredQName, objectValue);

            }
        }

        // Prepare the XQuery
        XQueryExpression exp;
        exp = staticContext.compileQuery(xQuery);

        // Run the XQuery
        StringWriter out = new StringWriter();
        exp.run(dynamicContext, new StreamResult(out), saxonProps);

        // Collect the content
        xqResult = out.toString();

The line that throws the error is:

dynamicContext.setContextItem(configuration.buildDocumentTree(new StreamSource(new StringReader(xmlData))).getRootNode());

Now I Googled around for the solution, but didn't find much info on this. Nor the XQ documentation has too many examples that I can learn off of. Any help would be appreciated. Thanks!

1
You are calling getSaxonConfig() at least twice, does that function ensure you return and use the same Configuration? At least the error message suggests that you are using two different ones.Martin Honnen

1 Answers

1
votes

Coming from 8.4, you're using API classes and methods (like StaticQueryContext and DynamicQueryContext) that are no longer best practice, if they work at all. The s9api interface was introduced around 9.1 and is more usable and more stable.

However, the error is because you have multiple Saxon Configuration objects. I can't see exactly what's going on because you haven't shown us the full picture, but creating a new Configuration() when there must already be an existing one for the getSaxonConfig() call to access looks like bad news.

I can't see what getSaxonConfig() does, but my guess is that if you change

Configuration configuration = new Configuration();

to

Configuration configuration = getSaxonConfig();

then the problem will go away.