Hi Bridger,

To be able to treat your field elements differently based on their @name,
you'd have to add some conditional logic to the return clause of your
"element(field)" case.  You could place this logic right in local:dispatch,
or you could create a new function, like local:field, which would take a
field element and check the value of @name.

You're right that typeswitch is limited to relatively simple sequence
patterns, and doesn't accommodate full XPath expressions.  Typically,
typeswitch performs the high level node type or element name check, and
then delegates more complex logic to functions.

Joe

On Thu, Feb 15, 2018 at 12:04 PM, Bridger Dyson-Smith <bdysonsm...@gmail.com
> wrote:

> Hi list --
>
> I'm trying to get a better understanding of identity transforms in Xquery
> and I don't understand the finer points of the approaches for dealing with
> specific elements.
>
> I've finally to become used to the XSLT approach, using a matching
> template to process `field[@name='first']`, e.g. would someone be willing
> to shine some light on different methods for dealing with this?
>
> Thanks very much for your time and trouble.
> Best,
> Bridger
>
> Example:
>
> declare variable $input :=
>   <docs>
>     <doc>
>       <title>ABC: The Alphabet</title>
>       <author>Some Person</author>
>       <fields>
>         <field name="first">First Field</field>
>         <field name="second">Second Field</field>
>       </fields>
>     </doc>
>   </docs>;
>
> declare function local:passthru( $node as node()* ){
>   local:dispatch($node/node())
> };
>
> declare function local:dispatch(
>   $nodes as node()*
> ) as item()* {
>   for $node in $nodes
>   return
>     typeswitch($node)
>       case text() return $node
>       case element(docs) return local:passthru($node)
>       case element(doc) return local:docf($node)
>       case element(title) return local:title($node)
>       case element(author) return local:author($node)
>       case element(fields) return local:passthru($node)
>       case element(field) return () (:return empty sequence:)
>       default return local:passthru($node)
> };
>
> declare function local:docf($node) {
>   <new>{local:dispatch($node/node())}</new>
> };
>
> declare function local:title($node) {
>   <new-title>{local:dispatch($node/node())}</new-title>
> };
>
> declare function local:author($node) {
>   <new-author>{local:dispatch($node/node())}</new-author>
> };
>
> local:dispatch($input)
>
> Output should look something like:
>
> <new>
>   <new-title>ABC: The Alphabet</new-title>
>   <new-author>Some Person</new-author>
>   <new-subject>First Field</new-subject>
>   <new-section>
>     <new-entry>Second Field</new-entry>
>   </new-section>
> </new>
>
>
> _______________________________________________
> talk@x-query.com
> http://x-query.com/mailman/listinfo/talk
>
_______________________________________________
talk@x-query.com
http://x-query.com/mailman/listinfo/talk

Reply via email to