Hi Marco,
I have updated the argument handling of the xquery:eval function such that items of untyped atomic are accepted as well. Indeed this is the standard behavior of most XQuery functions: if a node or untyped atomic is passed on as argument, it will be implicitly cast to a string.
Christian
On Wed, Oct 29, 2014 at 12:18 PM, Marco Lettere marco.lettere@dedalus.eu wrote:
Wow, that was tricky! Thanks a lot Christian and yes ... I'll pay defintely more attention to the use of data()/string() in the future! Cheers, Marco.
On 29/10/2014 11:44, Christian Grün wrote:
Hi Marco,
this is a shorter version of the code that causes the error message:
xquery:eval( 'declare variable $x external; $x', map { attribute a { 'x' }: 'x' } )
It takes some more lines to explain what's going on, though:
- The key of a map is being atomized. In the example, the attribute
will be converted to an item of type xs:untypedAtomic
- In earlier versions of the XQuery 3.1 Working Draft, all untyped
keys of a maps were cast to strings
- In a more recent version, map keys of type xs:untypedAtomic are not
cast anymore
- If xquery:eval is called, the untyped atomic cannot be cast to a QName
($x)
The easiest solution is to replace "data(@name)" with "string(@name)". I will additionally check if there is a clean way to do the cast implicitly in BaseX.
Hope this helps, Christian
[1] http://www.w3.org/TR/xquery-31/#doc-xquery31-MapConstructor
On Wed, Oct 29, 2014 at 10:49 AM, Marco Lettere marco.lettere@dedalus.eu wrote:
Hello all, I've stumbled upon an issue with the latest version and in particular the code I provide was working with 8.0 snapshot up to build 496C381 and with all previous official versions of course. Build 151df63 is the first build I'm aware of the difference. Shortly. In an input document I have a list of env nodes (sort of <env name="n">v</env>). They need to be parsed and "xquery:eval(uated)" in sequence because following env nodes may refer to preceding ones (i.e. <env name="n1">v1</env>, <env name="n2">{$n1}</env>). I've managed to do the job with the following code but now (as described in the preamble) I get the following cast exception in the xquery:eval:
Stopped at [...]/file, 9/31: ---> (this points to the line with the xquery:eval call) [XPTY0117] Cannot cast xs:untypedAtomic to xs:QName.
I've absolutely no idea why it started giving this error and even looking at the queryplan is too difficult in such a scenario for me. Anyone can help me out?
Thanks,
This is the smallest example of the code I was able to produce:
declare function local:declarations($env as map(*)){ string-join( map:keys($env) ! ( "declare variable $" || . || " external;") ) };
declare function local:updateenv($envnode as node(), $env){ let $q := local:declarations($env) || serialize($envnode) let $dynnode := xquery:eval($q, $env) return map:new(( map:entry($envnode/data(@name), $dynnode/text()), $env )) };
declare function local:buildenv($envnodes as node()*, $env as map(*)) { if(empty($envnodes)) then $env else let $envnode := $envnodes[1] let $newenv := local:updateenv($envnode, $env) return map:new(( $newenv, local:buildenv($envnodes[position() > 1], $newenv))) };
map:serialize( local:buildenv((<env name="n1">v1</env>, <env name="n2">another {{$n1}}</env> ), map{}) )