XSLT 和 Xpath 语法 > 如何引用“外部”范围中的元素
题
我的以下工作100%正确。不过为了满足我的好奇心...有没有办法在不声明 currentID 变量的情况下实现相同的目的?有没有办法从 Xpath“测试”条件中引用它?
条件中的xpath查询必须引用2个@id属性来查看它们是否匹配。
- “当前”@id
- 每个“祖先”@id
这是代码:
<xsl:variable name="currentID" select="@id" />
<xsl:attribute name="class">
<xsl:if test="count($currentPage/ancestor::node [@id = $currentID])>0">descendant-selected </xsl:if>
</xsl:attribute>
解决方案
既然您选择了 $currentID
从上下文节点:
<xsl:variable name="currentID" select="@id" />
你可以使用 current()
函数,它始终引用 XSLT 上下文节点:
<xsl:attribute name="class">
<xsl:if test="count($currentPage/ancestor::node[@id = current()/@id) > 0]">
<xsl:text>descendant-selected </xsl:text>
</xsl:if>
</xsl:attribute>
这样你就不需要变量了。
其他一些注意事项:
- 我建议使用
<xsl:text>
如上所示。这使您可以更自由地格式化代码并避免过长的行。 - 你不需要做
count() > 0
, ,只需选择节点就足够了。如果不存在,则返回空节点集。它始终评估为 false,而非空节点集始终评估为 true。
如果您通过以下方式引用节点 @id
定期在您的 XSL 样式表中, <xsl:key>
将变得有益:
<xsl:key name="kNodeById" match="node" use="@id" />
<!-- ... -->
<xsl:attribute name="class">
<xsl:if test="key('kNodeById', @id)">
<xsl:text>descendant-selected </xsl:text>
</xsl:if>
</xsl:attribute>
以上不需要 current()
因为在 XPath 谓词之外,上下文没有改变。还有,我不 count()
节点,因为这是多余的(如所解释的)。
其他提示
使用 current() 来引用模板处理的当前节点:
<xsl:if test="count($currentPage/ancestor::node [@id = current()/@id])>0">
蒂姆让我思考......我认为我把事情复杂化了,我尝试了以下有效的方法。
<xsl:if test="@id = $currentPage/ancestor::node/@id">descendant-selected </xsl:if>
XSLT 似乎很乐意将一个属性与一组属性进行比较,并评估其中任何一个匹配是否为 true?如果有人对为什么这样做有更好的解释或更好(更简洁)的东西,那么就把它写下来。
正如已经清楚的那样,引用“外部范围”不是问题,因为您可以使用“=”运算符进行直接比较。然而,在某些情况下,您确实需要 current() 以及更多,甚至 current() 也无法削减它(因为您需要在两个以上的上下文之间“加入”)。在这些情况下,XPath 2.0 的“for”表达式是不可或缺的。
你可以简单地这样做:
<xsl:if test="count($currentPage[ancestor::node/@id = @id])>0">descendant-selected </xsl:if>
不隶属于 StackOverflow