我的以下工作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])&gt;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) &gt; 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])&gt;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])&gt;0">descendant-selected </xsl:if>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top