Reputation: 11
I have a problem with xsl:include and xsl:apply-templates. I am doing some experiments with dynamic QName in xsl:call-template and I found a way how to do it but... it works only "inline" and not in included file.
If I do this, it works good (one file - file.xsl) - it show text "test" from match template:
<xsl:variable name="template" select="document('')/*/xsl:template"/>
<xsl:template match="xsl:template[@name='test']" name="test">
test
</xsl:template>
<xsl:template match="root">
<xsl:apply-templates select="$template[@name = $show]"/>
</xsl:template>
($show = 'test')
But, if I put first part to different file, e.g. template.xsl and then I will call it with xsl:include, it does NOT work. I don't have idea why.
<xsl:variable name="template" select="document('')/*/xsl:template"/>
<xsl:include href="template.xsl" />
<xsl:template match="root">
<xsl:apply-templates select="$template[@name = $show]"/>
</xsl:template>
Is there anybody who can help me with that please? xsl:include should put content of filename.xsl to parent template but it looks like it didn't
Note: I have XSLT 1.0
Edit 2015-12-10: Thank you guys for pointing to a problem. I am setting path to document('') dynamically now and it works like a charm! Problem was obviously on that blank document(''), thank you very much Michael and others.
<xsl:variable name="path"><xsl:value-of select="$show"/>.xsl</xsl:variable>
<xsl:variable name="templatePath" select="document($path)/*/xsl:template"/>
...
...
<xsl:template match="root">
<xsl:apply-templates select="$template[@name = $show]"/>
</xsl:template>
Upvotes: 1
Views: 599
Reputation: 163595
The reason that it doesn't work is that the expression
document('')/*/xsl:template
only selects xsl:template elements in the containing document.
The design pattern you are using is essentially a reinvention of the first (XSLT 1.0) version of Dimitre Novatchev's FXSL. I suggest you read up on that. IIRC, Dimitre's approach doesn't match xsl:template elements, but rather on elements whose names correspond to the names of the templates that you want to execute:
<xsl:variable name="names-fragment">
<A/>
<B/>
</xsl:variable>
<xsl:variable name="names" select="exslt:node-set($names-fragment)"/>
<xsl:template name="A" match="A">
<xsl:call-template name="B"/>
</xsl:template>
<xsl:template name="B" match="B">
<xsl:param name="target"/>
<xsl:apply-templates select="$names/*[name()=$target]"/>
</xsl:template>
Here the variable $names
is accessible in all stylesheet modules.
Of course, all this tomfoolery becomes unnecessary with higher-order functions in XSLT 3.0.
Upvotes: 0