0

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!

hell_storm2004
  • 1,401
  • 2
  • 33
  • 66
  • 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 Nov 25 '19 at 11:07

1 Answers1

1

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.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • Ah sorry. Get saxon config just returns the Configuration object which was initialized using `Configuration configuration = new Configuration();` – hell_storm2004 Nov 25 '19 at 11:33
  • You said I am using old API/Classes that are no longer recommended. Any suggestion on how to find the new stuff and run an XQ using the s9api? This code is more than 6 or 7 years old. It was lying there unchanged. Since it was stable and working, no one bothered to look in from time to time. Now due to migration, all of these need to be upgraded. – hell_storm2004 Nov 25 '19 at 11:36
  • 1
    Well, the simple change is to avoid creating a second Configuration. But if you want to use the s9api API, then the documentation is at http://www.saxonica.com/documentation/index.html#!javadoc/net.sf.saxon.s9api (start with the `Processor` class and its `newXQueryCompiler` method), and you can download samples in the saxon-resources download also available at www.saxonica.com – Michael Kay Nov 25 '19 at 12:47
  • Yeah. The double configuration object was causing the problem. In the meantime i was searching for samples. And I found this: https://www.saxonica.com/html/documentation/using-xquery/api-query/s9api-query.html . It doesn't have too many sample code, or at least I wasn't able to find it. But I will give it a red good go! Thanks for the help! – hell_storm2004 Nov 25 '19 at 13:07
  • 1
    Go to http://www.saxonica.com/download/download_page.xml and scroll down to "Additional resources". – Michael Kay Nov 25 '19 at 15:58