Using dynamic href in XSLT import/include?

2019-02-25 17:42发布

问题:

The <xsl:import> and <xsl:include> elements seem to behave quite specific. What I am trying to do:

<xsl:import href="{$base}/themes/{/settings/active_theme}/styles.xsl" />

I want to allow loading different themes for my application. I have a settings in my App which stores the "currently active theme" folder name in a xml node. Unfortunately the code above won't work. Does anybody know about a workaround to achieve what I want to do?

edit: just confirmed with a XSLT guru via Twitter... there's no nice way of doing this. Easiest solution in my case will probably be to seperate frontend and backend stylesheets and load them individually to the XSLTProcessor...

回答1:

xsl:import assembles the stylesheet prior to execution. The stylesheet can't modify itself while it is executing, which is what you are trying to achieve.

If you have three variants of a stylesheet for use in different circumstances, represented by three modules A.xsl, B.xsl, and C.xsl, then instead of trying to import one of these into the module common.xsl that contains all the common code, you need to invert the structure: each of A.xsl, B.xsl, and C.xsl should import common.xsl, and you should select A.xsl, B.xsl, or C.xsl as the principal stylesheet module when initiating the transformation.



回答2:

What I am trying to do:

<xsl:import href="{$base}/themes/{/settings/active_theme}/styles.xsl" />

This isn't allowed in any version (1.0, 2.0, or 3.0) of XSLT.

In XSLT 2.0 (and up) one may use the use-when attribute, but the conditions that may be specified are very limited.

One non-XSLT solution is to load the importing XSLT stylesheet as an XmlDocument and use the DOM API to set href attribute to the really wanted value -- only then invoke the transformation.