XSLT/XPath中的当前节点与上下文节点有何不同?

67
在XSLT中,“当前节点”和“上下文节点”的区别是什么?您可以在此处找到使用这两个术语的内容:http://www.w3.org/TR/xslt
何时使用其中一个?如何引用每个节点?
2个回答

82
当前节点是模板当前正在操作的节点。通常情况下,这也是上下文节点,但在嵌套的XPath表达式中(方括号中的部分)上下文节点具有特殊含义。在那里,它指代当前正在测试匹配的任何节点。因此,在XPath表达式内部上下文节点会发生变化,但是当前节点不会改变。
上下文节点可以用点符号(.)缩写或省略。这可能有点令人困惑,因为在嵌套表达式之外,点表示当前节点。(在这种情况下,当前节点恰好是上下文节点,因此可以说它只是近似地成为当前节点,并且更正确地称为上下文节点。但即使是规范在此处也将其称为当前节点。)
由于点号给出了上下文节点,在嵌套的XPath表达式中,用户需要一种方式来引用当前节点,即当前模板正在处理的节点。您可以通过使用current()函数来实现这一点。
在某些情况下,区分这两个节点是有用的。例如,假设您有以下XML:
<a>
    <b>
        <c>foo<footnote fn="1"/></c>
        <d>bar</d>
    </b>
    <b>
        <c>baz</c>
        <d>aak<footnote fn="2"/></d>
    </b>
    <b>
        <c>eep</c>
        <d>blech<footnote fn="2"/></d>
    </b>
    <footnote-message fn="1">Batteries not included.</footnote>
    <footnote-message fn="2">Some assembly required.</footnote>
</a>

假设现在您想将其转换为LaTeX格式,如下所示:

foo\footnote{Batteries not included.}
bar

baz
aak\footnote{Some assembly required.}

eep
blech\footnotemark[2]

关键是要确定脚注是否已经被使用过。如果这是您第一次遇到该脚注,您想要编写一个 \footnote 命令;否则,您想要编写一个 \footnotemark 命令。您可以使用以下 XSL 代码:

<xsl:choose>
    <xsl:when test="count(preceding::*[./@fn = current()/@fn]) = 0">\footnote{...}</xsl:when>
    <xsl:otherwise>\footnotemark[...]</xsl:otherwise>
</xsl:choose>

在这里,我们正在比较上下文节点的fn属性(来自preceding::*节点集的结果)与当前节点的fn属性。(实际上您不必说./@fn;您可以只说@fn。)

简而言之,上下文节点让您留在XPath谓词内部;当前节点到达谓词外部,回到当前模板正在处理的节点。


1
这与自轴有什么关系? - Devela

7

上下文节点

上下文节点XPath 位置步骤 的一部分,并且随着每个位置步骤而变化:

step1 / step2 / step3 / ...

其中每个步骤

axis::node-test[predicate]
  • 每个步骤都根据前面的步骤设置的上下文节点进行评估。
  • 然后,每个步骤选择成为后续步骤的上下文节点。
  • 在评估predicate时,上下文节点是沿着axis通过node-test的节点。
  • 可以使用.访问上下文节点。

当前节点

当前节点是XSLT 处理模型的一部分:1

  • 当前节点是与XSLT模板最匹配的源XML文档中的节点。
  • 当前节点成为匹配模板中每个XPath表达式的起始上下文节点。
  • 可以在XPath谓词中使用current()访问当前节点。

1虽然对于理解上下文节点和当前节点之间的基本差异没有影响,但请注意 XSLT 2.0中 评估上下文的描述已经改变。当前节点和当前节点列表的概念已被XPath概念上下文项, 上下文位置和上下文大小所取代。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接