How to use setContextItem when using callFunction
Added by Saurabh Jain almost 5 years ago
Hi,
I would like to pass a dom node to a function and extract value using XPath. I am getting Exception in thread "main" net.sf.saxon.s9api.SaxonApiException: There is no context item. Found while atomizing the first argument of fn:contains()
Here is the sample code
Configuration configuration = Configuration.newConfiguration();
Processor processor = new Processor(configuration);
XQueryCompiler xQueryCompiler = processor.newXQueryCompiler();
String fun = new String(Files.readAllBytes(Paths.get("query/funTest.xq")));
XQueryEvaluator qe = xQueryCompiler.compile(fun).load();
qe.setContextItem(new XdmAtomicValue("apple"));
Map<String, Object> javaMap = new HashMap<>();
javaMap.put("key1", "val1");
javaMap.put("key2", "val1");
javaMap.put("key3", "val1");
javaMap.put("key4", "val1");
qe.setExternalVariable(new QName("javaArgs"), new XdmExternalObject(javaMap));
XdmValue xdmValue = qe.callFunction(new QName(
"http://www.w3.org/2005/xquery-local-functions", "testJavaArgs"), new XdmValue[] {});
And content of funTest.xq
declare variable $javaArgs external; declare variable $testArgs external;
declare function local:testJavaArgs() {
let $discount := 12
return contains(., 'e')
};
0
However this works fine
XQueryExecutable exp = xQueryCompiler.compile("contains(., 'e')");
qe = exp.load();
qe.setContextItem(new XdmAtomicValue("apple"));
XdmValue result = qe.evaluate();
System.out.println("apple: " + ((XdmAtomicValue) result).getBooleanValue());
Replies (3)
Please register to reply
RE: How to use setContextItem when using callFunction - Added by Michael Kay almost 5 years ago
The global context item is not available within a function body. This would be exactly the same if you set it within the query, using declare context item
. You can access global variables, but not the global context item. It's a rather arbitrary rule; I think the reason for it is that many people would assume that a reference to "." within the function body was a reference to the context item of the function caller, rather than the global context item.
I suggest you use a global varaible here rather than the context item.
RE: How to use setContextItem when using callFunction - Added by Michael Kay almost 5 years ago
The relevant rule in the XQuery 3.1 spec is in §4.18:
[Definition: User defined functions are functions that contain a function body, which provides the implementation of the function as a content expression .] The static context for a function body includes all functions, variables, and namespaces that are declared or imported anywhere in the Prolog, including the function being declared. Its in-scope variables component also includes the parameters of the function being declared. However, its context item static type component is absent, and an implementation should raise a static error [err:XPST0008] if an expression depends on the context item.
RE: How to use setContextItem when using callFunction - Added by Saurabh Jain almost 5 years ago
Thanks Michael for quick response. Using global variable mechanism it works !!!
Regards Saurabh
Please register to reply