From: christophe g. <chr...@e-...> - 2012-10-09 13:52:25
|
Hi all I am trying to find a flexible way to scan xml documents (while keeping a ref to the nodes being scanned) with the help of the (very welcomed - thanks !) xQuery 3.0 facilities, and am getting a lot of very funny stuff when using map objects (2.1, rev 17278) ... Can somebody test the xquery below that simply goes through each node of the $test element and apply a function stored in a map object to each child element node, and please tell me why I do see the results I see. With the function defined in $map-ok, everything seems all right. $map-double (note the slight difference from "at" := ($node/@*), to "at" := $node/@*) returns a somehow dupplicated version of the provided $test node, while $map-error fails to run (stackoverflow error). using util:expand($test) doesn't help. My impression is that something goes wrong somewhere, but I am really not getting the why nor the where ... Thanks for the help and cheers, Christophe xquery version "3.0"; declare function local:scan($content as node()*, $model) { let $scan-map := map{ "scan.true" := function($node, $model, $test) {$node}, "scan.default" := function($node, $model) {$node} } let $model:= map:new(($scan-map, $model)) return for $root in $content return local:process-scan($root, $model) }; declare function local:process-scan($node as node(), $model) { typeswitch ($node) case document-node() return for $child in $node/node() return local:process-scan($child, $model) case element() return let $return := $model("scan.true")($node,$model, ()) return typeswitch($return) case map(*) return element {if($return("na") instance of xs:QName) then local-name-from-QName($return("na")) else $return("na")} { $return("at"), for $child in $return("ct") return local:process-scan($child, $model) } default return $model("scan.default")($node,$model) default return () }; let $test := <a> <b ns="b"> <c ns="c"/> </b> </a> let $map-ok:= map{ "scan.true" := function($node, $model, $test) { map { "na" := name($node), "at" := ($node/@*), "ct" := ($node/node()) } } } let $map-double:= map{ "scan.true" := function($node, $model, $test) { map { "na" := name($node), "at" := $node/@*, "ct" := ($node/node()) } } } let $map-error:= map{ "scan.true" := function($node, $model, $test) { map { "na" := name($node), "at" := ($node/@*), "ct" := $node/node() } } } return ( local:scan($test,$map-ok) (:returns what it should:) , local:scan($test,$map-double) (:returns all element nodes twice:) ) (: local:scan($test,$map-error) stackoverflow error :) |