Hi Christian and all,
Something interesting about this is that I think I saw that a direct recursion like this in BaseX or Saxon is not suitable for tail call optimization. Or, I ran out of memory trying this once. I wonder if something like SAX for XQuery implemented in XQuery is a useful idea for an extreme case of needing an identity transform.
Kendall
On 2/16/18, 8:56 AM, "basex-talk-bounces@mailman.uni-konstanz.de on behalf of Christian Grün" <basex-talk-bounces@mailman.uni-konstanz.de on behalf of christian.gruen@gmail.com> wrote:
Hi Bridger,
Questions like this are welcome!
A switch approach, as suggested by Liam, might look as follows:
declare function local:dispatch( $nodes as node()* ) as item()* { for $node in $nodes return if (not($node instance of element())) then ( $node ) else switch(name($node)) case 'docs' return local:passthru($node) case 'doc' return local:docf($node) case 'title' return local:title($node) case 'author' return local:author($node) case 'fields' return local:passthru($node) case 'field' return ( if($node/@name='first') then local:field-1($node) else if($node/@name='second') then local:field-2($node) else () ) default return () };
The nested if conditions for the 'field' element could be rewritten to a switch clause as well.
In most cases, I tend to use XQuery for transforming existing XML nodes. The 'update' keyword gives you a concise syntax for updating existing nodes [1]:
declare %updating function local:rename($node, $name) { rename node $node as $name }; $input/* update { local:rename(., 'new'), .//(title, author) ! (rename node . as 'new-' || name()), insert node element new-subject { .//field[@name = 'first']/text() } into ., insert node element new-section { element new-entry { .//field[@name = 'second']/text() } } into ., delete node .//fields }
In this little example, I have accommodated various different ways to modify existing nodes (calling a function, using paths and the simple map expression, …). As you can easily see, the approach is pretty different to the identity transformation in XSLT: Instead of building a new document, you are updating existing nodes. This can be both very powerful and concise, because you can address and update descendant nodes with a simple path expression, but it is mostly appropriate if your old and new documents look similar.
If you want to stick with the official XQuery Update 1.0 syntax, you can also use the more verbose copy/modiy/return statements (see the same link).
Hope this helps, feel free to ask for more details, Christian
[1] https://urldefense.proofpoint.com/v2/url?u=http-3A__docs.basex.org_wiki_XQue...