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

J. Zhang zhangjunte at gmail.com
Mon Feb 11 11:53:09 PST 2008


On Feb 11, 2008 10:07 AM, Michael Kay <mike at saxonica.com> wrote:
> > > what output would you like to see?
> >
> > I would like to preserve the original XML file, but only add
> > an extra tag, so I would like to have this output:
> >
> > <ead>
> >  <banana/>
> >  <archdesc>
> >    <dsc>
> >      <c00/>
> >      <SELECT>
> >      <c01/>
> >      </SELECT>
> >      <c02/>
> >    </dsc>
> >  </archdesc>
> >  <custard/>
> > </ead>
>
> In XSLT this is simply an identity template that copies all elements
> unchanged:
>
> <xsl:template match="*">
>   <xsl:copy><xsl:apply-templates/></xsl:copy>
> </xsl:template>
>
> (or a variation of that if you need to handle attributes)
>
> supplemented by a template for the element you want to change:
>
> <xsl:template match="c01">
>   <SELECT><xsl:next-match/></SELECT>
> </xsl:template>
>
> (You can write a more elaborate match pattern if you need to be more
> selective.)
>
> In XQuery you need to program the recursive descent by hand:
>
> declare function local:processNode($e as node()) as element() {
>   typeswitch ($e) {
>     case element(c01) return <SELECT>{$e}</SELECT>
>     case element() return
>       element {node-name($e)} {for $c in $e/child::node() return
> local:processNode($c)}
>     default return $e
>   }
> }
>
> local:processNode(doc('abc.xml')/*)
>
> plus a bit of extra logic if you need to handle attributes or namespaces.
>

Ok, this is what I am using:

declare function local:processNode($e as node()) as element()
{
 typeswitch ($e)
   case element(c01)
      return <SELECT>{$e}</SELECT>
   case element()
      return
         element {node-name($e)} {
            for $c in $e/child::node() return
               local:processNode($c)
         }
   default return $e
};

local:processNode(doc('ead_10748500.xml')/*)

...but I am getting an error when using that function:

  XPTY0004: Required item type of result of function
local:processNode() is element();
  supplied value has item type text()
Query processing failed: Run-time errors were reported

The error message is obvious, but probably typecasting won't work here.

Do you have any ideas?

jz


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


More information about the talk mailing list