[xquery-talk] Selecting everything before and after path, but without duplicated leafs

Michael Kay mike at saxonica.com
Mon Feb 11 15:13:53 PST 2008


> However, I like XQuery more. :) Simply because I want to 
> learn XQuery, I will ask one more question about this problem:
> 
> The function looks like this:
> 
> declare function local:processNode($e as node()) as node()* { 
>  typeswitch ($e)
>    case element(c01)
>       return <SELECT>{$e}</SELECT>
>    case element()
>       return
>          element {name($e)} {
>             for $c in $e/child::node() return
>                local:processNode($c)
>          }
>    default return $e
> };
> 
> local:processNode(doc('file.xml')/*)
> 
> 
> Instead of matching the element name, I would like to match 
> the entire path (node). In my case, I got the path 
> "/ead[1]/archdesc[1]/dsc[1]/c01[1]".

I think the best way to handle this is to declare either a global variable
or a second parameter to the processNode function, initialized to the value
of this path expression, and then replace the test for element(c01) by a
test against this instance:

  declare function local:processNode($e as node(), $selected as element())
as node()* {
   if ($e is $selected) then
      return <SELECT>{$e}</SELECT>
   else typeswitch ($e)
>    case element()
>       return
>          element {name($e)} {
>             for $c in $e/child::node() return
>                local:processNode($c, $selected)
>          }
>    default return $e
> };
> 
> local:processNode(doc('file.xml')/*, /ead[1]/archdesc[1]/dsc[1]/c01[1])

This is assuming you only want to select a single node. If you want to mark
all nodes that match some kind of pattern, then you'll have to implement
something akin to XSLTs pattern matching yourself. The natural solution
would be to use the above function and pass in a second parameter which is a
call-back function that determines whether the node matches or not;
unfortunately however XQuery 1.0 doesn't allow higher-order functions so
this isn't possible.

Michael Kay
http://www.saxonica.com/



More information about the talk mailing list