What Is xsl:use-package in XSLT 3.0?

The <xsl:use-package> declaration in XSLT 3.0 serves as the primary mechanism for importing and linking modular, independently compiled stylesheet packages. Unlike legacy inclusion mechanisms, it enables enterprise-grade software engineering practices in XSLT by establishing strict encapsulation boundaries, managing version dependencies, and allowing selective overriding or renaming of library components such as functions, templates, and modes.

Modular Packaging Versus Legacy Inclusion

Prior to XSLT 3.0, modular stylesheets relied heavily on <xsl:include> and <xsl:import>. While functional, these directives operate on a textual and tree-inclusion level, pulling all declarations into a single flat global scope. This frequently caused namespace collisions, made library refactoring risky, and prevented independent compilation.

XSLT 3.0 introduced <xsl:package> to define self-contained compilation units and <xsl:use-package> as the consumer-side link. A package exports only explicitly declared public or abstract components, while keeping private implementation details hidden. When a stylesheet or package invokes <xsl:use-package>, the XSLT processor links the pre-compiled package without exposing or interfering with internal helper functions or local variables.

Key Attributes and Dependency Resolution

The <xsl:use-package> element appears at the top level of a package or stylesheet declaration. It identifies target dependencies using standardized attributes:

During static analysis, the processor uses these attributes to locate, compile (if not already cached), and link the exact matching library binary or AST (Abstract Syntax Tree).

Encapsulation and Component Renaming with xsl:accept

To prevent naming collisions and manage interface boundaries, <xsl:use-package> uses child <xsl:accept> elements. Through <xsl:accept>, the importing module controls which public components of the imported package are exposed:

<xsl:use-package name="http://example.com/math-lib" package-version="1.0">
  <xsl:accept component="function" names="math:calculate-tax" visibility="public"/>
  <xsl:accept component="function" names="math:format-*" visibility="private"/>
</xsl:use-package>

Specialization and Component Customization with xsl:override

The <xsl:use-package> element also supports behavioral extension through the <xsl:override> child element. This allows developers to supply specialized implementations for public or abstract components defined in the base package without modifying the original library source code.

When a function or template is overridden, the new implementation takes precedence throughout the linked package's internal execution path, enabling dynamic polymorphism and library extension across separately maintained modules.

By enforcing strict boundaries, supporting versioned linking, and providing granular control over component visibility and overrides, <xsl:use-package> transforms XSLT into a scalable language suitable for large-scale, component-driven data transformation pipelines.