|
[XQuery Talk Mailing List Archive Home] [By Date] [By Thread] [By Subject] [By Author] [Recent Entries] [Reply To This Message] Selecting everything before and after path, but without duplicated leafsMichael Kay mike at saxonica.comMon 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:http://x-query.com/mailman/listinfo/talk] > Sent: 11 February 2008 10:53 > To: Michael Kay > Cc: http://x-query.com/mailman/listinfo/talk > Subject: Re: Selecting everything before and > after path,but without duplicated leafs > > On Feb 11, 2008 10:07 AM, Michael Kay <http://x-query.com/mailman/listinfo/talk> 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/ > > > > > >
|
Purchase Stylus Studio Online Today!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|






