使用条件将 XSL 变量设置为节点集

Posted

技术标签:

【中文标题】使用条件将 XSL 变量设置为节点集【英文标题】:Setting an XSL variable to a node-set using conditions 【发布时间】:2013-03-04 05:34:04 【问题描述】:

这个问题与XSL store node-set in variable 非常相似。主要区别在于,如果 XPath 没有找到与过滤器匹配的节点,我想返回第一个未过滤的结果。

我在这里的代码可以工作,但我觉得它是一种 hack,不是很好的 XSL 风格。在这种情况下,每个章节节点都由一个字符串 id 标识。变量showChapter 是标识章节的字符串。如果没有找到具有此 id 属性的章节,我想返回第一章。

相关代码:

<xsl:param name="showChapter" />

<!-- if $showChapter does not match any chapter id attribute, 
     set validShowChapter to id of first chapter. 
-->

<xsl:variable name="validShowChapter">
    <xsl:choose>
        <xsl:when test="/book/chapter[@id=string($showChapter)][position()=1]">
            <xsl:value-of select="$showChapter" />
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="/book/chapter[position()=1]/@id" />
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

<!-- I want $chapter to be a valid node-set so I can use it in 
     XPath select statements in my templates 
-->
<xsl:variable 
    name="chapter"
    select="/book/chapter[@id=string($validShowChapter)][position()=1]"
>

这种方法是否像我认为的那样糟糕,如果是这样,您能否指出一个更好的解决方案?我正在使用由 php5 的 XSLTProcessor 处理的 XSLT 1.0,但欢迎使用 XSLT 2.0 解决方案。

【问题讨论】:

【参考方案1】:

以下应该有效。在您的示例中,position()string() 的很多用法都是不需要的,顺便说一句:

<xsl:param name="showChapter" />

<xsl:variable name="foundChapter" select="/book/chapter[@id = $showChapter]" />
<!-- Will select either the first chapter in $foundChapter, or
     the first chapter available if $foundChapter is empty -->
<xsl:variable name="chapter" 
              select="($foundChapter | /book/chapter[not($foundChapter)])[1]" />

【讨论】:

非常感谢!我知道我写的东西太可怕了,不能成为最优雅的解决方案。

以上是关于使用条件将 XSL 变量设置为节点集的主要内容,如果未能解决你的问题,请参考以下文章

如何将命名空间前缀设置为有效负载 xsl

尝试选择节点时如何在 xsl 中使用变量?

XSL:在 XSL 1.0 中组合两个节点集

XSL 转换提取最小和最大日期

XSL 节点集:不按名称查找子元素

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