如何将 xsl:import 与路径名中的变量一起使用?

发布于 2024-11-01 18:46:16 字数 166 浏览 0 评论 0 原文

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

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

但我似乎无法在包含中使用变量($domain)。关于解决方法有什么建议吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小帐篷 2024-11-08 18:46:16

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

但如果您使用的是 XSLT 2.0,则可以将 条件包含 与 < code>use-when,如果您有一个可以在静态上下文中计算的表达式。

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.

人海汹涌 2024-11-08 18:46:16

通过添加静态参数,现在可以有条件地包含在 XSLT 3.0 中。静态参数可以在 xsl:includeuse-when 属性中使用。

现在我们可以使用 false() 的默认值声明参数,然后覆盖运行时所需的参数...

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

这是一个使用 Saxon-HE v9.7(也使用 Saxon-PE 9.5 进行了测试)。

XML 输入 (test.xml)

<doc>
    <foo/>
</doc>

主 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>

第一个可能包含的 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>

第二个可能包括 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>

命令行(将 inc2 设置为 true)

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

输出

<doc>
   <foo>INCLUDE FILE 2!!!</foo>
</doc>

这是另一个示例,使用上述文件(main.xsl 除外),这更像是原始问题,其中路径的一部分是变量。请注意 _href,它是 shadow 属性

主要 XSLT 3.0

<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="inc_number" as="xs:string" select="'1'" static="yes" required="no"/>

    <xsl:include _href="test_inc{$inc_number}.xsl"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

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>

Here's another example, using the above files (except main.xsl), that is more like the original question where part of the path is a variable. Note the _href which is a shadow attribute.

Main XSLT 3.0

<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="inc_number" as="xs:string" select="'1'" static="yes" required="no"/>

    <xsl:include _href="test_inc{$inc_number}.xsl"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>
絕版丫頭 2024-11-08 18:46:16

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

另一种方法是在运行时和启动转换之前加载 XSLT 样式表(作为 XML 文档),以动态设置任何所需 href 属性:include> 和/或 指令。

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

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.

笑梦风尘 2024-11-08 18:46:16

另一种解决方案是加载 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>

Another solution is to load an XML file and transform it by a set of rules (this file could even be a simple XSLT variant).

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文