代码之家  ›  专栏  ›  技术社区  ›  Mike

XSL,使用XML作为模板的参数

  •  7
  • Mike  · 技术社区  · 14 年前

    通过参数将XML传递给XSL模板可以吗?例如,下面我有一个模板 body 呼叫模板 test1 var1 . 然后我试着走到节点 a 使用XPATH

    <xsl:template name="test1">
        <xsl:param name="var1" />
        <fo:block>
            <xsl:value-of select="$var1/a" />
        </fo:block>
    </xsl:template>
    
    <xsl:template name="body">
        <xsl:call-template name="test1">
            <xsl:with-param name="var1" >
                <a>foo</a>
            </xsl:with-param>
        </xsl:call-template>
    </xsl:template>
    

    问题是,这会导致XSL解释器失败,并显示一条不可用的错误消息。我被迫使用一个封闭源代码的供应商系统来生成文档,所以我无法调试。但在进一步研究之前,我希望确认这是XSL的有效用法。

    1 回复  |  直到 14 年前
        1
  •  14
  •   collapsar    13 年前
    <xsl:template name="body"> 
        <xsl:call-template name="test1"> 
            <xsl:with-param name="var1" > 
                <a>foo</a> 
            </xsl:with-param> 
        </xsl:call-template> 
    </xsl:template>
    

    这个 $var1 传递给模板的参数在XSLT1.0/XPath1.0中很难使用,因为它是臭名昭著的RTF(Result Tree Fragment)类型。

    W3C XSLT 1.0 spec

    11.1结果树片段

    变量将一个额外的数据类型引入到 其他数据类型称为结果 到结果树片段而不是 四种基本XPath数据类型之一 结果树的片段。结果 树片段被等价地处理 只包含 单个根节点。然而 结果树上允许的操作 允许在节点集上使用。 安 树片段只有在 允许在字符串上使用 首先将字符串转换为 数字或布尔值)。尤其是 / , // [] 碎片。当允许的操作 在结果树上执行 片段,它完全按照 那就相当于

    复制结果树片段时 进入结果树(见[11.3 变量和参数值 与xsl:的副本]),然后是所有节点 是中根节点的子节点 序列到结果树。

    键入结果树片段依据 引用result类型的变量 树片段或调用扩展名 返回结果树的函数 其值是结果树片段。

    为了避免这种严重的设计决策,几乎每个XSLT处理器都有自己的扩展函数,通常称为 xxx:node-set() 在哪里 xxx 前缀必须绑定到供应商定义的命名空间。

    解决方案 :

    或者,如果您的XSLT处理器支持 EXSLT ,使用 exsl:node-set() EXSLT定义的扩展函数。

    以下是一些特定于供应商的命名空间:

    MSXML和.NET XslCompiledTransform,XslCompiledTransform

    xmlns:vendor="urn:schemas-microsoft-com:xslt"
    

    沙兰 (注意,函数名为: xxx:nodeset() !):

     xmlns:vendor="http://xml.apache.org/xalan"
    

    撒克逊(6.x):

     xmlns:vendor="http://icl.com/saxon"
    

    阿尔托瓦:

     xmlns:vendor="http://www.altova.com/xslt-extensions"
    

    所有实现EXSLT的XSLT处理器 :

    xmlns:vendor="http://exslt.org/common"
    

    <xsl:param> 不是动态构造的,可以避免

    功能如下:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes"/>
    
     <xsl:variable name="vrtfparamXML">
       <a>
         <b>foo</b>
       </a>
     </xsl:variable>
    
     <xsl:variable name="vparamXML" select=
     "document('')/*/xsl:variable
                    [@name='vrtfparamXML']/*"/>
    
     <xsl:template match="/">
       <xsl:copy-of select="$vparamXML/b"/>
     </xsl:template>
    </xsl:stylesheet>
    

    :

    <b xmlns:xsl="http://www.w3.org/1999/XSL/Transform">foo</b>
    

    注意