- From: Per Bothner <per@bothner.com>
- Date: Sat, 06 Mar 2004 08:13:34 -0800
- To: Xavier Franc <xfranc@online.fr>
- Cc: www-ql@w3.org, Chen Yabing <iscp0054@nus.edu.sg>
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