How Does collection() Work in XSLT 2.0?

In XSLT 2.0, the collection() function serves as a standardized mechanism to query, aggregate, and process multiple XML documents simultaneously within a single transformation. While XSLT 1.0 relied primarily on the document() function to load files one by one or through explicit URI node-sets, collection() returns an arbitrary sequence of document nodes from a URI-identified source or an implementation-defined default environment. This allows stylesheets to treat an entire directory, a database collection, or a designated list of XML resources as a unified dataset that can be filtered, sorted, and transformed using standard XPath 2.0 expressions.

Core Purpose and Syntax

The standard XPath and XSLT function signature is collection() or collection($uri as xs:string?). Calling the function without arguments accesses the processor's default collection of documents. When supplied with a URI string argument, the function resolves that URI against the base URI of the static context and returns a sequence of document nodes.

Unlike the doc() function, which resolves a single document, collection() abstracts the multi-document retrieval process. It outputs a flat sequence (document-node()*), enabling developers to apply path expressions across many files in parallel without manual recursion or external drivers.

Common Use Cases and Patterns

The primary use cases for collection() involve aggregation, batch processing, and global search across distinct XML documents.

A typical pattern involves assigning the retrieved sequence to a variable and then using for-each or template matching to iterate through each document:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xsl:template match="/">
        <master-catalog>
            <xsl:for-each select="collection('file:///data/catalogs?select=*.xml')//item">
                <xsl:copy-of select="."/>
            </xsl:for-each>
        </master-catalog>
    </xsl:template>

</xsl:stylesheet>

Processor-Specific URI Resolution

The W3C XSLT 2.0 and XPath 2.0 specifications define the semantics of collection(), but the exact syntax of the URI string argument depends heavily on the underlying XSLT processor.

In processors like Saxon, the URI parameter often supports custom query parameters to locate files on a filesystem. For example, collection('dir/?select=*.xml;recurse=yes') instructs the engine to recursively scan a folder for all XML documents. Other XML engines or native XML databases (such as BaseX or eXist-db) map collection URIs to specific database collections or catalog catalogs registered via an XML Catalog resolver.

Differences Between doc(), document(), and collection()

Understanding when to use collection() requires contrasting it with its related functions:

By decoupling the stylesheet logic from the exact number of incoming files, the collection() function provides a scalable and declarative approach to multi-document management in XSLT 2.0 workflows.