Dear BaseX team,
I face an issue with fn:generate-id.
Given: a document $doc parsed from the file system.Nodes obtained by
xquery_eval(EXPR, map{'':$doc}) and nodes obtained by $doc/EXPR
have the same identity (per $node1 is $node2), but the values generated by fn:generate-id differ.
Interestingly, if the document is constructed within the query, rather than read from a file, the values generated by fn:generate-id do not differ.
For a test see below.
At first sight, the issue may appear too obscure to justify efforts to remove it. HOWEVER, there is an important use case involved:
(a) expressions are read from a configuration and evaluated via xquery:eval; a map is constructed which associates for each node in the expression value its node id with other information (e.g. which of the configured expressions yielded this node) ;(b) then, when later nodes are visited via XPath, that other information should be retrieved (lookup in the map, using generate-id($node) as key) - AND THIS FAILS, as the XPath-provided nodes have ids which are different from the xquery:eval-provided nodes.
Could you please have a look?
With kind regards,Hans-Jürgen
Test query:========
let $doc1 := <root><foo/><bar/></root>
let $doc2 := doc('foobar.xml')/*
let $evalNodes1 := xquery:eval('*', map{'': $doc1})
let $evalNodes2 := xquery:eval('*', map{'': $doc2})
let $xpathNodes1 := $doc1/*
let $xpathNodes2 := $doc2/*
let $evalIds1 := $evalNodes1/concat(local-name(.), ' id=', generate-id(.))
let $xpathIds1 := $xpathNodes1/concat(local-name(.), ' id=', generate-id(.))
let $evalIds2 := $evalNodes2/concat(local-name(.), ' id=', generate-id(.))
let $xpathIds2 := $xpathNodes2/concat(local-name(.), ' id=', generate-id(.))
return (
'local doc - evalNodes1 = xpathNodes1 ?',
for $i in 1 to 2 return $evalNodes1[$i] is $xpathNodes1[$i],
'',
'local doc - evalNodes, ids:', $evalIds1,
'local doc - xpathNodes, ids:', $xpathIds1,
'',
'file doc - evalNodes1 = xpathNodes1 ?',
for $i in 1 to 2 return $evalNodes2[$i] is $xpathNodes2[$i],
'',
'file doc - evalNodes, ids:', $evalIds2,
'file doc - xpathNodes, ids:', $xpathIds2)
Document 'foobar.xml':=================
<root><foo/><bar/></root>
OUTPUT:=======
local doc - evalNodes1 = xpathNodes1 ?
true # OK!
true # OK!
local doc - evalNodes, ids:
foo id=id10
bar id=id12
local doc - xpathNodes, ids:
foo id=id10 # OK!
bar id=id12 # OK!
file doc - evalNodes1 = xpathNodes1 ?
true # OK!
true # OK!
file doc - evalNodes, ids:
foo id=id17
bar id=id18
file doc - xpathNodes, ids:
foo id=id31 # SHOULD BE id17bar id=id32 # SHOULD BE id18