Re: how to write such xquery?

Chen Yabing wrote:

 > Anyone else can help?

If you study the URL I posted, that should show you the techniques
you can use:  http://www.gnu.org/software/qexo/XQ-Gen-XML.html

But see a suggested solution below.

Xavier Franc wrote:

> Michael Kay wrote:

> I agree: in principle, recursive functions + typeswitch can emulate
> the template mechanism that exists in XSLT, but in practice it is not
> as convenient, not modular and --unless the typeswitch is smartly
> optimized-- probably not as efficient .
> 
> I believe it would be a great idea to introduce templates in XQuery, but
> I don't even dream that the WG would envisage it before ...  let's say 
> XQuery 3, in 2034...?  ;-)

I've earlier suggested adding "pattern types", which combined with
typeswitch will give most of the power and convenience of XSLT
templates, though without the automatic priority-based selections.
The idea is to allow "matching PATTERN" as another alternative for
SequenceType, at least in typeswitch:

declare function convert-children ($x) {
   for $y in $x/node() return convert-node($y)
};

declare function convert-node($x) {
typeswitch ($x)
   case matching chapter/title (: title in chapter :)
     return <h1>{convert-children($x)}<h1>
   case matching section/title (: title in section :)
     return <h2>{convert-children($x)}<h2>
   case matching title (: default for title :)
     return <h3>{convert-children($x)}<h2>
   ... other cases ...
   default return convert-children($x) };

Note that this is quite compact and convenient, though it
doesn't have the convenience of xsl:import or priorities.
(The priority is handwired to be the order in the typeswitch.)
One could of course add templates in addition.

Chen Yabing's problem doesn't require parent context, so it
can be simply expressed without "matching", though because
he does need to match type attributes he can't just use
typeswitch.  I'm not sure I understand the problem correctly,
but would something like this work?

declare function convert-children ($x) {
   for $y in $x/node() return convert-node($y)
};

declare function convert-node($x) {
   if ($x instance of element(d,*) and $x[@dno="d002"])
     then $x
   else if ($x instance of element() and $x//d[@dno="d002"])
     then element {node-name($x)} {$x/@*, convert-children($x)}
   else if ($x instance of document())
     then document {convert-children($x)}
   else () };
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

Received on Saturday, 6 March 2004 11:14:04 UTC