XQuery/Transformation idioms

Motivation
Document transformation using the basic typeswitch statement applies the same transformation to an element independent of where it occurs in the document. The transformation also preserves document order since it processes elements in document order. In comparison with XSLT, XQuery lacks some mechanisms such as modes, priority and numbering. This article addresses some of these limitations.

Example
The example uses a custom XML schema to markup the contents of the book "Search: The Graphics Web Guide", Ken Coupland, a compendium of websites. This document is formatted with a site-specific schema. The document contains site elements which are tagged with a category, and also category elements which provide a commentary on the category. For comparison this dataset is used in a student case study which uses XSLT for transformations.

Customising the identity transformation
The module code is only a basic skeleton which we would edit to customize the transformation. In this example we will transform the document to HTML. This will require editing a number of the element converters.

Default action
Change the  function to provide a different default action. For example:

would include the content of the node but remove the tag and its attributes.

Change element name
Site descriptions will be rendered as divs:

Ignore element
The 'class' element is not needed:

Define transformation
The image element should be transformed to an html  element using the uri as the source:

Transformation depends on context
By default all elements with the same name anywhere in the document are transformed in the same way. Often this is not what is required:

Reordering elements
Each site is to be rendered in the order name, uri and then the rest of the sub-elements:

Numbering categories
The xsl:number instruction provides a mechanism to generate hierarchical section numbers. This instruction is very powerful. In specific cases we can generate numbers using functions.

For example to number the categories we can use this function to create a number for a node in a sequence of siblings. Note that the number is based on the order of nodes in the original document, not the transformed document (as does xsl:number).

and call this function when transforming category names:

Parameterisation
The transformation can clearly be applied to different documents, but often the same transformation is to be used in different contexts. XSLT provides parameters and variables which are global to all templates.

In XQuery we can either declare global variables in the module or pass one or more parameters around the functions ( module generation is helpful here).

....

Generating an index
XSLT uses the mode mechanism to allow the same template to be processed in multiple ways. A common use case is where the same transformation must generate both an index and the content.

Several approaches suggest themselves. We could mimic the XSLT approach by passing an additional mode parameter in the calls and choose which transformation to apply in each function. Alternatively we append the mode to the function name. It is more difficult to use context (either global or passed) because the mode will need to be updated.

The simplest approach is to use use two typeswitch transformation and combine the results at a higher level. This clearly separates the two modes of transformation. The technique of module generation is helpful here.

Complex transformation
The overall HTML document can be structured in the transformer for the root element. The page uses the blueprint stylesheets. Each category of site is rendered, with the sites which are classified in that category.

Completed transformation
The full XQuery module now looks like this: