> The XQuery Processor
EvalExpr ::= UsingClause? "eval" "{" ExprSingle "}"
UsingClause ::= "using " "$" VarName ("," "$" VarName)*
The Eval expression first computes the value of its target expression in the context of the surrounding query. The result of this computation is atomized and cast as a string, then parsed and evaluated in a new static context and dynamic context derived from the contexts of the enclosing query at the global (top-level) scope. The derived contexts contain declarations for, and values of, the variables bound by the optional UsingClause. The values are taken from the innermost in-scope variable in the enclosing query with the same QName as the variable being declared.
The evaluated query may contain its own prolog, but may not be a library module, may not contain schema imports, and may not declare external variables. In all other respects, the evaluated query behaves like a regular query.
As eval introduces a distinct static context, it is not an error if the prolog of the evaluated query declares variables and/or functions shadowing components with the same name of the original query. However, the evaluated query may not declare global and/or external variables with names conflicting with the bindings specified by the UsingClause (which are implicitly declared in the evaluated query's static context).
(: Invalid Example (Using Clause) :)
let $x := 10 return
using $x eval {
"declare variable $x := 11;
$x + 1"
}
The query above is invalid as it re-declares the UsingClause bindings, which are implicitly defined in the evaluated prolog. It should raise err:XQST0049
(: Global Var Access :)
declare variable $x := 41;
eval { concat ("$x", "+", "1") }
The above query is valid and produces the result 42. It illustrates that evaluated code has access to global variables of the enclosing query.
(: Global Var and Function Access :)
declare variable $g := 11;
declare function local:f1 ($a) { $g + $a };
let $x := 10 return
using $x eval { "
declare function local:f2 () { $g + $x };
local:f1 ($x) + local:f2 ()
"}
This example, which in a conforming implementation should return the integer 42, illustrates that both global variables and user-defined functions from the enclosing query are available to the evaluated query, which may in turn contain its own user-defined functions.
(: Namespaces :) declare namespace ns1 = "myns"; declare variable $ns1:x := 1; declare variable $ns1:y := 40; eval { ' declare namespace ns2 = "myns"; declare variable $ns2:x := 2; $ns1:x + $ns1:y ' }
In this example, the namespace prefix ns1 is inherited by the evaluated query, which also binds the prefix ns2 to the same namespace. The correct result for this query is 42.
(: Invalid (wrong use in FLWOR) :)
let $x := 42 return eval { "$x" }
This eval query attempts to use a FLWOR variable from the surrounding query without declaring it in the UsingClause; it should raise err:XPST0008 (undefined variable).
(: Atomization :)
declare variable $n := <a><b>1</b><b>+$x</b></a>;
declare variable $x :=2;
eval { $n }
This example should return 3 (nodes are atomized before being passed to eval).
(: Invalid (Using with equal QNames) :) declare namespace ns1 = "myns"; declare namespace ns2 = "myns"; let $ns1:x := 3 return using $ns1:x, $ns2:x eval { "$ns1:x" }
Since the UsingClause lists two variables with equal QName's, this query should raise err:XQST0049
(: Invalid (Expecting single Item) :)
eval { 1 to 2 }
As eval expects a single item, this query should raise err:XPTY0004
(: Var Access :) let $x := "21" return using $x eval { concat ($x, " + xs:double ($x)") }
This eval expression accesses $x in two ways — both in the ExprSingle and in the evaluated code. The result should be 42.
(: Var Access over User def Function :)
declare variable $x := 20;
declare function local:f () { $x };
let $x := 22 return
using $x eval { "$x + local:f ()" }
The correct answer is 42. This query illustrates that references to global variables within a user-defined function's body are resolved in the original dynamic context that the function was compiled against, not in the innermost dynamic context available.