Reusing stylesheets¶
A real transformation is rarely one file. As it grows, the same scaffolding —
formatting rules, common element templates, shared helpers — gets copied between
projects. The fix is the same as in any other language: factor the shared parts
into a base stylesheet and let each project pull it in. XSLT offers two
top-level elements for this, xsl:include and xsl:import, and the difference
between them is entirely about precedence.
xsl:include — textual merge, same precedence¶
xsl:include is the simple one. It takes the templates from another stylesheet
and merges them in as if you had pasted them at the point of inclusion. Everything
ends up at the same import precedence.
- Pulls in every template from
base.xslat the same precedence as the rules written here. It is a top-level element — a direct child ofxsl:stylesheet. - The
cdtemplate that handles these can live inbase.xsl; the merge makes it available exactly as if it were defined locally.
Same precedence means conflicts are errors
Because an included stylesheet sits at the same precedence as the including
one, two templates matching the same nodes with the same priority is a genuine
conflict. The XSLT 1.0 spec lets a processor either signal an error or pick the
last one — it is processor-dependent, so never rely on it. Use include
only when the files are partitioned so no rule overlaps.
xsl:import — lower precedence, so you can override¶
xsl:import brings in another stylesheet too, but the imported templates get
lower import precedence than the importing stylesheet. That single rule is
what makes overriding possible: when both define a template for the same nodes,
the importing stylesheet wins, no conflict, no error.
xsl:import must come first
All xsl:import elements must appear before every other top-level element
in the stylesheet — before any template, variable, output declaration, even
before xsl:include. A processor will reject an import that follows other
top-level content.
| main.xsl | |
|---|---|
- Must be the first top-level element.
base.xslis now at lower precedence. - This
cdtemplate overrides whateverbase.xslmatched forcd, with no conflict — the higher-precedence (importing) definition simply wins.
include vs import at a glance¶
xsl:include |
xsl:import |
|
|---|---|---|
| Precedence of pulled-in rules | same as host | lower than host |
| Can the host override them? | no — same precedence | yes — host wins cleanly |
| Conflicting matches | error / processor-dependent | resolved by precedence |
| Position among top-level elements | anywhere | must be first |
| Reach the overridden rule | n/a | xsl:apply-imports |
Worked example: override one template, keep the rest¶
Here is the common shape. base.xsl provides a generic cd template that the
whole organisation shares:
- The generic rendering of a
<cd>. Most projects are happy with it as-is.
One project wants the same overall structure but a richer cd line — with the
artist, and the price tagged. It imports the base and overrides only the
cd template; the catalog template is inherited untouched.
- First, as required.
base.xslis now lower-precedence. - Overrides the base
cdtemplate. The basecatalogtemplate still fires and still callsapply-templates select="cd"— but now this rule answers. xsl:apply-importsruns the template this one overrode — the lower-precedencecdfrombase.xsl— against the same current node. So we add the artist, then delegate the title/price line back to the base instead of duplicating it.
Run against the catalog:
apply-imports is super for templates
Think of it as calling the base class's method. It does not take a select —
it re-applies the imported templates for the current node only, letting an
override decorate the inherited output rather than replace it wholesale.
Where href is resolved
For both include and import, href is resolved relative to the
stylesheet that contains it — not relative to the source document or the
working directory. If main.xsl and base.xsl sit side by side,
href="../base.xsl" is correct; a base in a subfolder would be
href="../common/base.xsl".
Next¶
Pulling in other stylesheets has a sibling: pulling in other data.
External documents covers document(), which lets a
transformation read a second XML file at run time.