xquery:eval - static context?
Saturday, 30 April 2016 · 1 message
HR
Hans-Juergen Rennau30 Apr 2016 07:47 #
Dear BaseX team,
a question concerning the static context used by
xquery:eval. It seems to me that the static context is not inherited from the location of the evaluating call. Therefore arises the question how to call user-defined functions within code evaluated by xquery:eval. Please consider this example: Attempt #1:=========================================================== declare namespace f="http://www.foxpath.org/xquery-functions";declare function f:num2($number) {2 * $number};
let $inlineFunctionText := "function($number) {f:num2($number)}"
let $f := xquery:eval($inlineFunctionText)
return $f(1)
=========================================================== Executing this, an error is raised: [XPST0081] No namespace declared for 'f:num2'.
Adding a namespace declaration does not help:
Attempt #2:===========================================================
declare namespace f="http://www.foxpath.org/xquery-functions";
declare function f:num2($number) {2 * $number};
let $inlineFunctionText :=
"declare namespace f='http://www.foxpath.org/xquery-functions';
function($number) {f:num2($number)}"
let $f := xquery:eval($inlineFunctionText)
return $f(1)
=========================================================== Now I get this error: [XPST0017] Unknown function: Q{http://www.foxpath.org/xquery-functions}num2.
The only (?) way out is pass in the function a parameter:
Attempt #3:===========================================================
declare namespace f="http://www.foxpath.org/xquery-functions";
declare function f:num2($number) {2 * $number};
let $inlineFunctionText :=
"declare namespace f='http://www.foxpath.org/xquery-functions';
declare variable $num2 external;
function($number) {$num2($number)}"
let $context := map{'num2': f:num2#1}
let $f := xquery:eval($inlineFunctionText, $context)
return $f(1)
===========================================================Result: 2Ok!
Fortunately, the passed in function does inherit its own static context (as it should, per spec), so that it may call other functions themselves not known to the inline function expression:
Attempt #4:===========================================================
declare namespace f="http://www.foxpath.org/xquery-functions";
declare function f:num2($number) {2 * $number + f:num3($number)};
declare function f:num3($number) {3 * $number};
let $inlineFunctionText :=
"declare namespace f='http://www.foxpath.org/xquery-functions';
declare variable $num2 external;
function($number) {$num2($number)}"let $context := map{'num2': f:num2#1}
let $f :=
xquery:eval($inlineFunctionText, $context)
return $f(1)
===========================================================Result: 5Okissimo! So my question is whether it is by design or by bug that xquery:eval "forgets" the static context in place where the invocation of xquery:eval occurs. And I emphasize the great practical relevance of the question as it impacts the possibility of using within the evaluated expression user-defined functions.
Cheers,Hans-JürgenWritten for BaseX 8.4. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery