2013-03-04 41 views
1

此问题与XSL store node-set in variable非常相似。主要区别在于,如果XPath找不到与过滤器匹配的节点,我想返回第一个未过滤的结果。使用条件将XSL变量设置为节点集

我在这里的代码工作,但我觉得它是一个黑客和不好的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]" /> 
+0

非常感谢您!我知道我正在写什么是最可怕的解决方案。 – Vlad 2013-03-04 08:22:50