1

我有以下工作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>
4

5 回答 5

3

由于您$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>如上所示。这使您可以更自由地格式化代码并避免过长的行。
  • 您不需要做 a count() > 0,只需选择节点就足够了。如果不存在,则返回空节点集。它总是计算为假,而非空节点集总是计算为真。

@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()节点,因为这是多余的(如解释的那样)。

于 2009-12-04T10:07:20.060 回答
2

使用 current() 来引用模板处理的当前节点:

<xsl:if test="count($currentPage/ancestor::node [@id = current()/@id])&gt;0">
于 2009-12-04T08:15:53.937 回答
1

蒂姆让我思考......我想我已经把事情复杂化了,我尝试了以下有效的方法。

<xsl:if test="@id = $currentPage/ancestor::node/@id">descendant-selected </xsl:if>

XSLT 似乎很乐意将一个属性与一组属性进行比较,并在其中任何一个匹配时评估 true?如果有人能更好地解释为什么会这样或者更好(更简洁),那么就把它记下来。

于 2009-12-04T00:43:02.630 回答
1

正如已经很清楚的那样,引用“外部范围”不是问题,因为您可以使用“=”运算符进行直接比较。但是,在某些情况下,您确实需要 current() 以及更多,甚至 current() 也不能削减它(因为您需要在两个以上的上下文之间“加入”)。在这些情况下,XPath 2.0 的“for”表达式是必不可少的。

于 2009-12-07T22:13:08.143 回答
0

你可以简单地做:

<xsl:if test="count($currentPage[ancestor::node/@id = @id])&gt;0">descendant-selected </xsl:if>
于 2009-12-03T23:34:04.903 回答