XSLT - Importing and Including Stylesheets with <xsl:import> and <xsl:include>?
In XSLT, large transformation projects often require multiple stylesheets to manage complex logic efficiently. Instead of placing all templates, variables, and functions in a single file, developers can divide the code into several smaller stylesheets. XSLT provides two mechanisms for combining stylesheets: <xsl:include> and <xsl:import>. Although both allow one stylesheet to use another, they serve different purposes and have distinct behaviors.
Why Use Multiple Stylesheets?
As XSLT applications grow, maintaining a single stylesheet becomes difficult. Separating functionality into multiple files offers several advantages:
-
Better organization of code.
-
Easier maintenance and updates.
-
Reusability of common templates.
-
Improved collaboration among developers.
-
Simplified debugging and testing.
For example, one stylesheet may handle formatting, another may process customer data, and a third may generate reports. These files can then be combined into a master stylesheet.
Understanding <xsl:include>
The <xsl:include> element allows one stylesheet to directly incorporate another stylesheet.
Syntax
<xsl:include href="commonTemplates.xsl"/>
The href attribute specifies the location of the stylesheet to include.
How It Works
When an XSLT processor encounters <xsl:include>, it effectively copies the contents of the referenced stylesheet into the current stylesheet. The included stylesheet becomes part of the main stylesheet as if all its content had been written directly in the file.
Example
Main stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:include href="header.xsl"/>
<xsl:template match="/">
<html>
<body>
<h1>Employee Report</h1>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Included stylesheet (header.xsl):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="employee">
<p>
<xsl:value-of select="name"/>
</p>
</xsl:template>
</xsl:stylesheet>
The processor treats both stylesheets as one combined stylesheet.
Characteristics of <xsl:include>
-
Used for modularizing code.
-
Included templates have the same precedence as templates in the including stylesheet.
-
Duplicate template definitions may cause conflicts.
-
Suitable when combining related stylesheet components.
Understanding <xsl:import>
The <xsl:import> element also incorporates another stylesheet, but it introduces the concept of import precedence.
Syntax
<xsl:import href="baseStylesheet.xsl"/>
Placement Rule
Unlike <xsl:include>, all <xsl:import> elements must appear before any other top-level elements except namespace declarations.
Correct:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="base.xsl"/>
<xsl:template match="/">
...
</xsl:template>
</xsl:stylesheet>
Incorrect:
<xsl:template match="/">
...
</xsl:template>
<xsl:import href="base.xsl"/>
This would generate an error.
Purpose of <xsl:import>
The primary purpose of importing is to allow customization or overriding of existing templates.
Suppose a base stylesheet provides general transformation rules, but a specific project requires modified behavior. The importing stylesheet can override selected templates while retaining all other functionality from the base stylesheet.
Example
Base stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="employee">
<p>Default Employee Template</p>
</xsl:template>
</xsl:stylesheet>
Main stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="base.xsl"/>
<xsl:template match="employee">
<p>Customized Employee Template</p>
</xsl:template>
</xsl:stylesheet>
The customized template takes precedence because it belongs to the importing stylesheet.
Import Precedence
One of the most important concepts in XSLT is import precedence.
When multiple templates match the same node:
-
Import precedence is considered first.
-
Template priority is considered next.
-
Document order is considered last.
Stylesheets that import others have higher precedence than the imported stylesheets.
Example:
<xsl:import href="base.xsl"/>
Templates in the current stylesheet override templates in base.xsl.
This mechanism supports stylesheet inheritance and customization.
Using Multiple Imports
A stylesheet can import several other stylesheets.
Example:
<xsl:import href="common.xsl"/>
<xsl:import href="formatting.xsl"/>
<xsl:import href="reporting.xsl"/>
The order matters.
The stylesheet imported later has higher precedence than one imported earlier.
For example:
<xsl:import href="A.xsl"/>
<xsl:import href="B.xsl"/>
Here, templates in B.xsl have higher precedence than templates in A.xsl.
Calling Overridden Templates with <xsl:apply-imports>
Sometimes a template overrides an imported template but still wants to execute the original version.
XSLT provides <xsl:apply-imports> for this purpose.
Example:
Imported template:
<xsl:template match="employee">
<p>Original Employee Information</p>
</xsl:template>
Overriding template:
<xsl:template match="employee">
<h2>Employee Details</h2>
<xsl:apply-imports/>
</xsl:template>
Output:
<h2>Employee Details</h2>
<p>Original Employee Information</p>
This allows developers to extend existing functionality rather than completely replacing it.
Key Differences Between Include and Import
| Feature | xsl:include | xsl:import |
|---|---|---|
| Purpose | Combine stylesheets | Extend or override stylesheets |
| Precedence | Same as current stylesheet | Lower than importing stylesheet |
| Override Support | No special precedence | Supports overriding |
| Placement | Anywhere among top-level elements | Must appear before other top-level elements |
| Use Case | Code organization | Style inheritance and customization |
Best Practices
Organize Shared Templates
Place reusable templates in separate stylesheets and include them where needed.
Use Import for Customization
When creating project-specific versions of a generic stylesheet, use imports instead of includes.
Avoid Duplicate Templates
Duplicate template matches can lead to ambiguity and maintenance issues.
Maintain Logical Structure
Keep stylesheets grouped by functionality such as formatting, validation, reporting, and data processing.
Document Dependencies
Clearly document which stylesheets depend on others to simplify maintenance.
Common Errors
Incorrect Import Position
<xsl:template match="/">
...
</xsl:template>
<xsl:import href="base.xsl"/>
This causes a compilation error because imports must appear first.
Missing File Path
<xsl:include href="missing.xsl"/>
The processor cannot locate the referenced stylesheet.
Circular References
File A includes File B, and File B includes File A.
This creates an infinite loop and results in an error.
Conflicting Templates
Including multiple stylesheets with identical template matches can cause unexpected behavior.
Conclusion
<xsl:include> and <xsl:import> are essential tools for creating modular, maintainable, and reusable XSLT applications. While <xsl:include> simply combines multiple stylesheets into one logical unit, <xsl:import> introduces a hierarchy that enables template overriding and customization. Understanding the differences between these two mechanisms allows developers to design scalable XSLT solutions that are easier to maintain, extend, and reuse across multiple projects.