Essentially I want do this in XSL:
<xsl:include href="_domains/{$domain}/templates/header.xsl" />
But I can't seem to use a variable ($domain) in the include. Any suggestions on a work around?
xsl:import
and xsl:include
are resolved at compile time, and do not support runtime expansion.
Except, if you are using XSLT 2.0, you can use conditional inclusion with use-when
, if you have an expression that can be evaluated in a static context.
As explained by @lavinio, in XSLT 2.0 the use-when
attribute may be used to allow a certain degree of "compile-time" inclusion of an xslt instruction, however this is only limited to testing conditions that can can be determined from values in the static context and from these dynamic context values: current date and time, and implicit time zone.
Another approach is to load the XSLT stylesheet (as an XML document) at runtime and before initiating the transformation to dynamically set the href
attribute of any desired <xsl:include>
and/or <xsl:import>
instructions.
This technique is used by the XPath Visualizer to dynamically change the XSLT stylesheet that then evaluates the user-specified XPath expression and formats the XML document with all selected and visible nodes -- highlighted.
With the addition of static parameters, it is now possible to conditionally include in XSLT 3.0. Static parameters can be used in the use-when
attribute of the xsl:include
.
Now we can declare parameters with default values of false()
and then override the ones we need at run time...
<xsl:param name="someparam" as="xs:boolean" select="false()"
static="yes" required="no"/>
<xsl:include href="include_me.xsl" use-when="$someparam"/>
Here is a full working example tested with Saxon-HE v9.7 (also tested with Saxon-PE 9.5).
XML Input (test.xml)
<doc>
<foo/>
</doc>
Main XSLT 3.0 (test_main.xsl)
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="inc1" as="xs:boolean" select="false()"
static="yes" required="no"/>
<xsl:param name="inc2" as="xs:boolean" select="false()"
static="yes" required="no"/>
<xsl:include href="test_inc1.xsl" use-when="$inc1"/>
<xsl:include href="test_inc2.xsl" use-when="$inc2"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
First possible included XSLT 3.0 (test_inc1.xsl)
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="foo">
<xsl:copy>INCLUDE FILE 1!!!</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Second possible included XSLT 3.0 (test_inc2.xsl)
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="foo">
<xsl:copy>INCLUDE FILE 2!!!</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Command line (setting inc2
to true)
java -cp "saxon9he.jar" net.sf.saxon.Transform -s:"test.xml" -xsl:"test_main.xsl" inc2="true"
Output
<doc>
<foo>INCLUDE FILE 2!!!</foo>
</doc>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With