28

使用 XSLT 1.0,我试图从本质上创建一个小节点集,然后将其作为参数传递给模板,如下所示:

<xsl:call-template name="widget">
  <xsl:with-param name="flags">
    <items>
      <item>widget.recent-posts.trim-length=100</item>
      <item>widget.recent-posts.how-many=3</item>
      <item>widget.recent-posts.show-excerpt</item>
    </items>
  </xsl:with-param>
</xsl:call-template>

这个想法是,然后从widget模板中我可以编写如下内容:

<xsl:value-of select="$flags/item[1]" />

显然我得到编译错误..我怎样才能实现这种事情?

4

2 回答 2

31

XSLT 1.0 中有一种方法(非标准)可以动态创建临时树并在其上评估 XPath 表达式,但是这需要使用xxx:node-set()函数

xsl:variable每当在 an或 an的主体内动态创建节点时xsl:param,该xsl:variable/的类型xsl:param是 RTF(结果树片段)和 W3 XSLT 1.0 规范。严格限制可以针对 RTF 评估的 XPath 表达式的种类。

作为一种解决方法,几乎​​每个 XSLT 1.0 供应商都有自己的xxx:node-set()扩展函数,该函数接受一个 RTF 并从中生成一个正常的节点集。

前缀(或您选择的任何其他前缀)绑定到的命名空间因xxx供应商而异。对于 MSXML 和两个 .NET XSLT 处理器,它是:"urn:schemas-microsoft-com:xslt". EXSLT 库使用命名空间:"http://exslt.org/common". 这个命名空间 EXSLT 在许多 XSLT 1.0 处理器上实现,如果可能,建议使用它的xxx:node-set()扩展。

这是一个简单的例子

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:ext="http://exslt.org/common"
  exclude-result-prefixes="ext msxsl"
 >
 <xsl:template match="/">
  <xsl:variable name="vTempRTF">
   <a>
    <b/>
   </a>
  </xsl:variable>

  <xsl:copy-of select="ext:node-set($vTempRTF)/a/*"/>
 </xsl:template>
</xsl:stylesheet>
于 2010-10-07T13:07:19.910 回答
7

好吧,我设法通过以下方式解决了这个问题:

首先将自定义命名空间添加到您的样式表,例如xmlns:myns="http://my.ns.com"

然后在样式表的顶部定义节点集:

<myns:recent-posts-flags>
    <item>widget.recent-posts.trim-length=100</item>
    <item>widget.recent-posts.how-many=3</item>
    <item>widget.recent-posts.show-excerpt</item>
</myns:recent-posts-flags>

然后通过以下方式引用:

<xsl:call-template name="widget">
    <xsl:with-param name="flags" select="document('')/*/myns:recent-posts-flags" />
</xsl:call-template>

这行得通,但对我来说,在<xsl:with-param>标签本身中定义节点集仍然是理想的,就像我给出的第一个例子一样。有人认为这是可能的吗?

于 2010-10-07T10:25:14.697 回答