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

J. Zhang zhangjunte at gmail.com
Mon Feb 11 17:38:42 PST 2008


On Feb 11, 2008 4:13 PM, Michael Kay <mike at saxonica.com> wrote:
> 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.


Selecting a single node is what I need. When I use your function, I am
getting this error:

XPST0003: XQuery syntax error in #...elected) then return <SELECT>{#:
    expected "else", found ">"
Static error(s) in query

I don't see any mistake in the syntax. The error is probably generated
by the "if" statement, I assume it can take a "return"?

This is what I have copied from you:

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('/var/www/html/data/iisg/ead_10748500.xml')/*,
/ead[1]/archdesc[1]/dsc[1]/c01[1])


Thanks,

jz

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


More information about the talk mailing list