创建节点集并作为参数传递

Posted

技术标签:

【中文标题】创建节点集并作为参数传递【英文标题】:Create node set and pass as a parameter 【发布时间】:2011-04-22 06:49:13 【问题描述】:

使用 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]" />

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

【问题讨论】:

【参考方案1】:

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

每当在 xsl:variablexsl: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>

【讨论】:

【参考方案2】:

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

首先将自定义命名空间添加到您的样式表中,例如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>

这可行,但对我来说,在&lt;xsl:with-param&gt; 标记本身中定义节点集仍然是理想的,就像我给出的第一个示例中一样.. 有人认为这可能吗?

【讨论】:

+1 这是常见问题解答,也在specs:In addition, the xsl:stylesheet element may contain any element not from the XSLT namespace, provided that the expanded-name of the element has a non-null namespace URI. (...) Such elements can provide, for example, information used by extension elements or extension functions, information about what to do with the result tree, information about how to obtain the source tree, metadata about the stylesheet, structured documentation for the stylesheet. 您还需要定义“myns”,否则转换将失败。我发现了这一点:***.com/questions/5873954/namespaces-in-xslt 帮助我确定将 xmlns:myns="localhost" 添加到我的 xsl:stylesheet-node 解决了这个问题。 这正是我在答案第二行所说的。 是的。只有我读得不好,谷歌搜索得快。 >_ 您好,你们中有人设法在 php 中使用这种方法吗?似乎 php XSLTProcessor 无法很好地处理document('') 调用...

以上是关于创建节点集并作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章

在 Mongoose 中传递 REST URL 参数作为查询条件

为什么这个函数重命名作为参数传递的LinkedList节点?

将命名空间从 java 传递给 xslt,并使用 java 中的参数作为 xslt 中的节点

在 msxsl 中将节点作为参数传递:来自 XSLT for-each 的脚本 javascript 函数不起作用

尝试创建可以在应用程序域之间作为参数 c# 传递的类

在 Java 中将数组作为参数传递时创建数组