XSL transformations with the transform module

Introduction

The transform (in the http://exist-db.org/xquery/transform function namespace) module provides functions for directly applying an XSL stylesheet to an XML fragment within an XQuery script. The full list of functions and their documentation is in the Function Documentation Library. This article discusses some of the highlights and main uses for this module.

transform:transform() and transform:stream-transform()

transform:transform()

This XSL transformation functions have the following signatures:

transform:transform($input as node()?, $stylesheet as item(), $parameters as node()?) as node()?
transform:transform($node-tree as node()*, $stylesheet as item(), $parameters as node()?, $attributes as node()?, $serialization-options as xs:string?) as node()?

transform:transform expects the node to be transformed in the first argument $input. If $input is an empty sequence, the function returns immediately.

The XSL stylesheet will be read from the location specified in $stylesheet, which should be either an URI or a node. If $stylesheet is of type xs:anyURI, the function will attempt to load the stylesheet from the specified location. A relative URI is interpreted as a file path. The function then tries to locate the stylesheet in the same way as imported XQuery modules, i.e. relative to the module load directory determined by the static XQuery context.

Some examples for referencing the stylesheet:

transform:transform($root, doc("/db/styles/style.xsl"), ())

Creates the stylesheet from a document node.

transform:transform($root, xs:anyURI("style.xsl"), ())

Loads the stylesheet from the file style.xsl. The function usually expects the file to reside in the same directory as the main query.

transform:transform($root, xs:anyURI("http:exist-db.org/style.xsl"), ())
transform:transform($root, xs:anyURI("xmldb:exist:///db/styles/style.xsl"), ())

The last two examples try to load the stylesheet from an URI. However, the "xmldb:" URI points to a resource stored in the database.

The stylesheet will be compiled into a template using the standard Java APIs (javax.xml.transform). The template is shared between all instances of the function and will only be reloaded if modified since its last invocation.

The $options parameter can be used to pass stylesheet parameters to the XSL processor as an XML fragment - for example:

<parameters>
    <param name="param1" value="value1"/>
    <param name="param2" value="value2"/>
</parameters>

This will set the stylesheet parameter param1 to the string value value1, and in the XSL stylesheet, the parameter can then be referenced as follows:

<xsl:param name="param1"/>
There are two special parameters named "exist:stop-on-warn" and "exist:stop-on-error". If set to value "yes", eXist will generate an XQuery error if the XSL processor reports a warning or error.

Optionally a set of two arguments can be specified. With the $attributes argument it is possible to pass attributes to the transformation factory; Verify the Java or Saxon documentation for more details:

<attributes> <attr name="param1" value="value1"/> <attr name="param2" value="value2"/> </attributes>

The serialization-options argument specifies serialization options in the same way as if they were passed to the "declare option exist:serialize" expression. An additional serialization option, "xinclude-path", is supported, which specifies a base path against which xincludes will be expanded (if there are xincludes in the document). A relative path will be relative to the current module load path.

transform:stream-transform()

Identical to the transform:transform function, but it directly streams the transformation result to the HTTP request output stream and doesn't return anything. The function is thus only usable in a web context. Note that the servlet output stream will be closed afterwards.