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
[1] https://urldefense.proofpoint.
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
com/v2/url?u=http-3A__docs. basex.org_wiki_XQuery- 5FUpdate-23update&d=DwIFaQ&c= DS6PUFBBr_ KiLo7Sjt3ljp5jaW5k2i9ijVXllEdO ozc&r=JgwnBEpN1c-DDmq- Up2QMq9rrGyfWK0KtSpT7dxRglA&m= CoL2BpluuEvyW- WdbNgt2gSoIHO77nRzlVsE_agjRO4& s= zf5U1x9A37aU0FMwZDLFgizGEI8ALj n0uGST2cZGCdw&e=