Dynamic XSLT Invocation Using XPath 3.1 fn:transform
The fn:transform() function introduced in XPath and
XQuery 3.1 enables developers to invoke XSLT transformations dynamically
within an XML query expression. By encapsulating transformation
parameters, source documents, and stylesheets inside an XPath map,
fn:transform() bridges document querying and complex
structural transformation without requiring external processing engines
or multi-step execution scripts.
The Mechanism of
fn:transform()
Prior to XPath 3.1, running an XSLT transformation required a
dedicated host environment, such as an external script, an Ant build
file, or a proprietary processor API. The fn:transform()
function standardizes this capability directly within the XPath/XQuery
data model.
The function uses a single argument: an XPath map specifying transformation parameters. This map-based design allows full flexibility, as options can be constructed dynamically at runtime.
Key Map Options
The input map to fn:transform() controls how the XSLT
engine executes:
- Stylesheet Inputs: You can provide the stylesheet
via
stylesheet-location(a URI),stylesheet-node(an in-memory XML node containing the XSLT), orstylesheet-text(a string containing XSLT markup). - Source Documents: The target XML data can be
supplied via
source-node(an existing in-memory document node) orsource-location(a URI). - Parameters and Variables: The
stylesheet-paramsoption accepts a nested map of QNames and values passed directly to<xsl:param>elements in the stylesheet. - Output Configuration: The
delivery-formatoption specifies whether the output should be returned as raw parsed nodes (document-node), serialized strings (serialized), or saved directly via secondary result documents.
Dynamic Processing Capabilities
Because fn:transform() accepts nodes and strings
directly, stylesheets do not need to be static files stored on disk. An
XPath or XQuery expression can:
- Generate Stylesheets on the Fly: A query can
construct an XSLT document dynamically based on incoming user input or
data schema variations, and pass that generated node directly to
stylesheet-node. - Conditionally Route Transformations: A query can
evaluate the content of an XML document and choose different stylesheets
at runtime using standard
if-then-elseexpressions or dynamic URI lookups. - Chain Multi-Stage Pipelines: Transformations can be
chained directly in memory. The result of one
fn:transform()call can serve as thesource-nodefor a subsequent transformation within a single query expression.
Handling Transformation Results
The fn:transform() function returns a map containing the
results of the transformation. By default, the primary result document
is accessible under the output key of the returned map:
let $options := map {
"stylesheet-location": "format-report.xsl",
"source-node": /data/report
}
let $result := fn:transform($options)
return $result?output
If the stylesheet produces multiple output documents using
<xsl:result-document>, secondary outputs appear in
the returned map associated with their respective output URIs.
Advantages for XML Query Workflows
Dynamic invocation of XSLT through fn:transform()
eliminates the operational overhead of managing external transformation
pipelines. It unites the targeted extraction capabilities of XPath with
the templating and rule-based strengths of XSLT, enabling
self-contained, highly adaptable XML processing workflows inside
standard-compliant processors such as Saxon or BaseX.