如何在路径名中使用xsl:import和变量?

时间:2011-04-14 20:47:51

标签: xslt

基本上我想在XSL中执行此操作:

<xsl:include href="_domains/{$domain}/templates/header.xsl" />

但我似乎无法在include中使用变量($ domain)。有关解决方案的任何建议吗?

4 个答案:

答案 0 :(得分:5)

xsl:importxsl:include在编译时解析,不支持运行时扩展。

但是,如果您使用的是XSLT 2.0,则可以将conditional inclusionuse-when一起使用,如果您的表达式可以在静态上下文中进行评估。

答案 1 :(得分:1)

正如@lavinio所解释的那样,在XSLT 2.0中,use-when属性可用于允许某种程度的“编译时”包含xslt指令,但这仅限于可以测试的条件可以根据静态上下文中的值以及这些动态上下文值来确定:当前日期和时间以及隐式时区。

另一种方法是在运行时加载XSLT样式表(作为XML文档),然后在启动转换之前动态设置任何所需href的{​​{1}}属性, /或<xsl:include>说明。

XPath Visualizer使用此技术动态更改XSLT样式表,然后评估用户指定的XPath表达式,并使用所有选定和可见节点格式化XML文档 - 突出显示。

答案 2 :(得分:0)

添加static parameters后,现在可以有条件地包含在XSLT 3.0中。静态参数可以在use-when的{​​{1}}属性中使用。

现在我们可以使用默认值xsl:include声明参数,然后在运行时覆盖我们需要的参数...

false()

以下是使用Saxon-HE v9.7(也使用Saxon-PE 9.5测试)测试的完整工作示例。

XML输入(test.xml)

<xsl:param name="someparam" as="xs:boolean" select="false()" 
  static="yes" required="no"/>  
<xsl:include href="include_me.xsl" use-when="$someparam"/>

主XSLT 3.0 (test_main.xsl)

<doc>
    <foo/>
</doc>

首先可能包含XSLT 3.0 (test_inc1.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>

第二种可能包括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 1!!!</xsl:copy>
  </xsl:template>

</xsl:stylesheet>

命令行(将<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> 设置为true)

inc2

<强>输出

java -cp "saxon9he.jar" net.sf.saxon.Transform -s:"test.xml" -xsl:"test_main.xsl" inc2="true"

答案 3 :(得分:0)

另一种解决方案是加载XML文件并通过一组规则对其进行转换(该文件甚至可以是简单的XSLT变体)。

<xsl:param name="domain">_default</xsl:param>

<xsl:variable name="header-template"
   select="document( concat('_domains/', $domain, '/templates/header.xml' ) )" />

<xsl:template name="header">
  <xsl:apply-templates mode="transform" select="$header-template"/>
</xsl:template>