[xquery-talk] Selecting everything before and after path,
but without duplicated leafs
Michael Kay
mike at saxonica.com
Mon Feb 11 11:08:31 PST 2008
Sorry, I started writing the function to return elements only and then
changed my mind. The type signature of the function should be "as node()*"
rather than "as element()".
Michael Kay
http://www.saxonica.com/
> -----Original Message-----
> From: J. Zhang [mailto:zhangjunte at gmail.com]
> Sent: 11 February 2008 10:53
> To: Michael Kay
> Cc: talk at x-query.com
> Subject: Re: [xquery-talk] Selecting everything before and
> after path,but without duplicated leafs
>
> 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