XQuery from a Java application
Added by Anonymous over 18 years ago
Legacy ID: #3785964 Legacy Poster: RCathelin (rcathelin)
Hello, I’m a new Saxon user and I need some help. My question is about the Xquery call from a Java application. (you will find at the end of this mail the code corresponding to my question). I don’t understand why the “testMethod” of my TestClass is called two times. This behavior seems to appear only if a no empty list is returned (If my method returns an empty list or returns a simple String, the testMethod is called only one time). When I follow the execution, I can see that the ExtensionFunctionCall.call is called two times. If somebody can test this code … Thanks, Best regards. Rémi Cathelin ================================================ import net.sf.saxon.Configuration; import net.sf.saxon.query.DynamicQueryContext; import net.sf.saxon.query.StaticQueryContext; import net.sf.saxon.query.XQueryExpression; import net.sf.saxon.trans.XPathException; public class MainTest { protected static StaticQueryContext mStaticContext; protected static DynamicQueryContext mDynContext; public static void main(String[] args) { System.out.println(“BEGIN”); String aXqueryExpr = "declare namespace test="java: TestClass ";doc('toto')/test:testMethod('text:revision')"; // Create configuration Configuration iConfiguration = new Configuration(); iConfiguration.setHostLanguage(Configuration.XQUERY); // Create static context mStaticContext = new StaticQueryContext(iConfiguration); //Create dynamic context mDynContext = new DynamicQueryContext(iConfiguration); XQueryExpression iQuery = null; try { iQuery = mStaticContext.compileQuery(aXqueryExpr); } catch (XPathException e) { e.printStackTrace(); } List iResultsList = null; try { iResultsList = iQuery.evaluate(mDynContext); } catch (XPathException e) { e.printStackTrace(); } System.out.println(“END”); } public class TestClass { public static List testMethod (XPathContext xPathContext, String param){ ArrayList list = new ArrayList(); System.out.println("into TestClass. testMethod ()!”); list.add(new String("hello!")); return list; } } Console MSG: BEGIN into TestClass. testMethod ()! into TestClass. testMethod ()! END
Replies (1)
RE: XQuery from a Java application - Added by Anonymous over 18 years ago
Legacy ID: #3786526 Legacy Poster: Michael Kay (mhkay)
There's a rule in XPath 2.0 that with an expression like A/B, either all the values of B must be atomic, or all the values must be nodes. The two paths are significantly different, because in the case where nodes are returned, the nodes have to be sorted; this means there are two completely separate paths in the code. In the vast majority of cases, Saxon can work out at compile time which case will apply. But in your case B is a call on an external Java function, so this analysis wasn't possible. There's a comment in the code that says "this case is very rare so performance isn't important". The way Saxon handles it is to peek at the first value in the B sequence, and then go into either the "read all atomic values" or "read all nodes" path, depending what it finds. This means that the first item in the sequence will be read twice. As XQuery is a functional language, the processor is entirely at liberty to make decisions like this, and so long as your external function doesn't have side-effects there should be no adverse consequences. Writing external functions that do have side-effects is definitely not recommended. Michael Kay
Please register to reply