2011-10-29 48 views
7

其他XSL文件我有一个小问题,就是有没有办法动态包含另一个XSL?例如:动态包括在XSLT

<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" /> 
+0

使用 bvb1909

回答

2

你不能这样做。原因很简单:

XSL将首先扩大了xsl:编译期间包括,它先天下之忧。那时你的“变量”是不知道的,不能被知道,编译后你不能改变编译好的变换。另外,href是一个统一资源定位符而不是一个XPath表达式,因此你不能只在其中扩展一个变量。

+0

OK,那不过是愚蠢的......在PHP一个简单的包括()解决了这个问题......我真的需要这个,为什么这种方式开发的? – Master345

+0

我不知道为什么,但XSLT!= PHP恐怕:) – FailedDev

+1

@row叟这是与你的启动响应的精确翻译“好了,但是这是愚蠢的”。这里是:“我相信香蕉不在我口中,每次我想吃香蕉都是愚蠢的,当我吃PHP时,它很美味。”技术monkey-hoot(代替这里的任何名字,也许是PHP)实现了一个包含你想要的时尚的方式,但绝不会让错误的是,技术不同 - monkey-hoot(替换这里的任何名字,也许是xsl)实现一个包含不同的。 – DwB

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" /> 

是违法的具有在<xsl:include>href属性的可变参考。根据W3C XSLT 1.0和XSLT 2.0规范,此属性的值必须是URI引用。

然而,如果$PathToWeb变量的值的转变的开始前已知的,其可以以多种方式来动态地产生一个样式表表示,其中上述<xsl:include>语句包含的愿望的URI中使用(替代后提及$PathToWeb与所需的值:

  1. 生成从当前一个新的样式表,使用XSLT

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

方法2已经使用了11年的XPath Visualizer动态设置中使用的select属性的精确值来选择用户输入的XPath表达式中选择的所有节点,并产生一个HTML文件表示突出显示所有选定和可见节点的XML文档。

+1

我XMLSpy的根据经验确定的是''不允许XPath表达式作为其'href'属性的值,而'的'一样。不过,我无法在规范中找到任何支持这一点的内容。两者之间真的有区别,还是它是一个错误/专有扩展? (我实际上甚至没有使用变量,只是像{'test'}这样的任何表达式。) – Dabbler

+1

这不是一个错误。 AVT允许用于'的'href'属性,目的是允许生成多个结果文档。 ''和''之间有很大的区别。前者只能在编译时处理,后者在运行时处理。 –

+3

我不知道许多编程语言的结构在执行过程中修改了程序,所以如果允许动态xsl:includes,那将是相当令人吃惊的。至于规范,xsl:include的规则是''而xsl:result-document的规则是'

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"/> 
    ... 

的URI解析器的resolve方法将得到import://stackoverflow.com/xslhref参数。 import://可以作为一个“特殊”的标识方案定制包括,所以你可以检测到它,并创建/返回其指向必需的文件javax.xml.transform.Source。例如:

TransformerFactory tf = TransformerFactory.newInstance(); 
URIResolver delegate = tf.getURIResolver(); 
tf.setURIResolver(new CustomURIResolver(delegate)); 

然后,内部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; 
    } 

添加openTemplate()方法,其包括逻辑来动态确定XSL文件打开。

0

在PHP中,如在其他机制,它是一个多步骤的过程中使用XSL样式表:

1)创建从XSL文件中的SimpleXML或DOMDocument对象。

2)创建一个XSLTProcessor对象。

3)将XSL文档对象导入到处理器对象中。

4)在XML数据文件上运行转换。

在1)之后,XSL能够在作为步骤3)的一部分被编译之前被操纵。正是在这里,xsl:include元素可以根据需要动态插入根元素。

因此,动态插入的xsl:包括:

1.1)使用XPath |的getElementById |的getElementsByTagName检查用于您可能需要额外的样式表元素的存在数据的XML。

1.2)动态创建xsl:include元素离开XSL的XML对象的根元素。

就是这样。在步骤3),修改后的XSL XML对象将被编译,就好像它是从一开始那样构建的。

当然,在1.2版本中,来自其他XSL文档对象的ANY节点(不仅仅是xsl:include或xsl:import)可以添加到基本XSL文档对象中的ANY节点,从而提供更好的控制。然而,所有XSL样式表的正确的xsl:template结构应该使插入xsl:include元素变得更直接。

0

我2个便士一个简单的(但有效)替代(仅设置伪码用于说明进行谨慎:)该方法的

概要。 的备选解决方案可以由一个简单的包装脚本(例如shell,bash脚本或其他)来调用您的主要xsl,使用名称xslt模式,主要xslt文件,一个简单的(空白)静态指定的xslt文件。

在主要的xsl中,包含一个静态xsl文件,它将调用/加载所有动态包含的xslt。然后,主要的xsl将以2种模式运行:普通模式(未指定模式),它将在其中加载扩展xsl文件以及静态xls文件,并处理任何输入文件,或者执行任何有用的内容做。第二种模式,预处理器模式,将用于加载指定的xsl实例/文件。该模式将作为主处理运行的预处理阶段调用。主xslt的处理流程是使用指定的预处理器模式调用它,然后用指定的正常处理模式再次调用它。

实现提示: 对于每个xlator,定义一个n扩展xslt文件ext_xsl_container,其目的是包含任何扩展名xslt。 例如

<xsl:stylesheet > 
    <!-- main xslt --> 
     <xsl:import href="../xsl/ext_xsl_container.xsl/> 
     <!--param: list of dynamically specified extension xsl --> 
     <xsl:param name="extXslUrlList"/> 
     <!--param:preprocessor mode flag, with default set to false --> 
     <xsl:param name="preProcModeLoadXslF" select="false()" type="xs:boolean" 
<!-- param: path to the staticall included ext_xsl_container: with default value set --> 
    <xsl:param name="extXslContainerUrl" select="'../xsl/ext_xsl_container.xsl'"/> 

     <xsl:if test=" ($preProcModeLoadXslF=true())" > 
      <xsl:call-template name="loadDynamicXsl" mode="preprocess_load_xsl" 
     </xsl:if> 
     .... 
    </xsl:stylesheet> 

的ext_xslt_container样式表将包括任何扩展XSLT文件。它可以在运行时通过编辑(作为xml文档)动态更新,为扩展xsl样式表添加include语句。 如

<!-- ext xsl container : ext_xsl_container.xsl--> 
<xsl:stylesheet 
    <xsl:include href="ext_xsl_container.xsl"/> 

    .... 
</xsl:stylesheet 

创建一个小的模板,说template_load_ext_xsl,具有分配的模式,说模式= “preprocess_load_xsl” 如

<xsl:template name="loadDynamicXsl" mode="preprocess_load_xsl"> 
    <!-- param: path to the staticall included ext_xsl_container--> 
    <xsl:param name="extXslContainerUrl"/> 
    <!--param: list of dynamically specified extension xsl --> 
    <xsl:param name="extXslUrlList"/> 

    <!-- step 1, [optional ] open the ext Xsl container file --> 
    <!-- step 2 [optional] clear contexts of the ext X -- > 
    <!-- step3 compile a list of include elements, one per each ext Xsl file --> 
    <!-- step 4 [optional] create a union of the include elements created with the content of the xsl container file : ie append content > 
<!-- step 5 : write the union list of incudes to the ext XSL container file --> 
<!-- DONE ---> 

</xsl:template> 

模板将作为参数,ex_xsl_container的名字,和扩展XSL文件(包括路径)的列表 它就会打开ext_xsl_container文件作为一个XML文档,添加(选择追加,或明确的文件,并添加新的代码)每个扩展语句:XSL,保存文件和退出

下,当你运行在正常执行模式的主要XSL,它预订购包括模板loadDynamicXsl,这将inturn包括在运行时specifed扩展XSLT文件

创建一个简单的包装脚本(如bash中,或shell脚本),它将取得主xslt的参数,并运行预处理器模式。该脚本会简单地调用主XSLT两次,如果用于预处理模式的选项已启用,使在第一次运行的预处理模式,其次是在正常模式下的第二个呼叫