在XSLT中动态包含其他XSL文件

Mas*_*345 8 xslt markup xslt-1.0

我有一个小问题,有没有办法动态包含另一个xsl?例如:

<xsl:variable name="PathToWeb" select="'wewe'"/>
<xsl:include href="http://{$PathToWeb}/html/xsl/head.xsl" />
<xsl:include href="http://{$PathToWeb}/html/xsl/navigation.xsl" />
<xsl:include href="http://{$PathToWeb}/html/xsl/promo.xsl" />
<xsl:include href="http://{$PathToWeb}/html/xsl/3columns.xsl" />

<xsl:include href="http://{$PathToWeb}/html/xsl/footer.xsl" />
Run Code Online (Sandbox Code Playgroud)

Dim*_*hev 5

我有一个小问题,有没有办法动态包含另一个xsl?例如:

<xsl:variable name="PathToWeb" select="'wewe'"/> 
<xsl:include href="http://{$PathToWeb}/html/xsl/head.xsl" /> 
<xsl:include href="http://{$PathToWeb}/html/xsl/navigation.xsl" /> 
<xsl:include href="http://{$PathToWeb}/html/xsl/promo.xsl" /> 
<xsl:include href="http://{$PathToWeb}/html/xsl/3columns.xsl" /> 

<xsl:include href="http://{$PathToWeb}/html/xsl/footer.xsl" />
Run Code Online (Sandbox Code Playgroud)

href属性中包含变量引用是非法的<xsl:include>.根据W3C XSLT 1.0和XSLT 2.0规范,此属性的值必须是URI引用.

但是,如果$PathToWeb变量的值在转换开始之前是已知的,则可以通过多种方式使用它来动态生成样式表表示,其中<xsl:include>上面的语句包含所需的URI(在$PathToWeb用必需的URI替换引用之后)值:

  1. 使用XSLT 从当前样式表生成新样式表.

  2. 将样式表加载为XmlDocument对象.然后找到相应的<xsl:include>元素并将其href属性设置为所需的值.最后,使用代表样式表的如此修改的XmlDocument调用转换.

方法2.已在XPath Visualizer中使用了11年,以动态设置select用于选择用户输入的XPath表达式选择的所有节点的属性的确切值,并生成表示所有选定和可见的XML文档的HTML文档节点突出显示

  • 我不知道许多编程语言都有在执行期间修改程序的结构,所以如果允许动态xsl:includes则会相当令人惊讶.至于规范,xsl:include的规则是`<xsl:include href = uri-reference />`而xsl:result-document的规则是`<xsl:result-document href?= {uri-reference}`:那些花括号很重要,如2.2表示法中所述. (3认同)
  • 什么是"不正确的语法"?如果你的意思是问题的引用 - 是的,这是非法的.但这是*问题*,而不是答案,这只是解释这是非法的. (2认同)

min*_*das 5

我以不同的方式解决了这个问题,对于使用Java和XSLT的人来说可能很有用(这个解决方案特定于使用javax.xml.transform包的人).

XSLT变换器工厂允许设置自定义URI解析器.假设您的XSLT看起来像

<?xml version="1.0" encoding="utf-8"?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" version="4.0" encoding="UTF-8"/>
    <xsl:include href="import://stackoverflow.com/xsl"/>
    ...
Run Code Online (Sandbox Code Playgroud)

URI解析器的resolve方法将import://stackoverflow.com/xsl作为href参数获取.import://可以作为自定义包含的"特殊"标识符方案,因此您可以检测它并创建/返回javax.xml.transform.Source指向必需文件的方案.例如:

TransformerFactory tf = TransformerFactory.newInstance();
URIResolver delegate = tf.getURIResolver();
tf.setURIResolver( new CustomURIResolver( delegate ) );
Run Code Online (Sandbox Code Playgroud)

然后,里面CustomURIResolver:

  public Source resolve( String href, String base )
    throws TransformerException {
    Source result = null;
    URI uri = null;

    try {
      uri = new URI( href );
    }
    catch( Exception e ) {
      throw new TransformerException( e );
    }

    // The XSLT file has a URI path that allows for a file to be included
    // dynamically.
    if( "import".equalsIgnoreCase( uri.getScheme() ) &&
        "stackoverflow.com".equalsIgnoreCase( uri.getAuthority() ) ) {
      result = openTemplate();
    }
    else {
      result = getDelegate().resolve( href, base );
    }

    return result;
  }
Run Code Online (Sandbox Code Playgroud)

添加一个openTemplate()包含逻辑的方法,以动态确定要打开的XSL文件.


Fai*_*Dev 3

你不可以做这个。原因很简单:

XSL 将在编译期间首先扩展 xsl:include,然后再执行其他操作。那时,您的“变量”不知道也不可能被知道,并且一旦编译,您就无法更改已编译的转换。此外,href 是统一资源定位器而不是 XPath 表达式,因此您不能只在其中扩展变量。