xslt中的自轴

Self axis in xslt

<element>
  <bye>do not delete me</bye>
  <hello>do not delete me</hello>
  <hello>delete me</hello>
  <hello>delete me</hello>
</element>

应用于上述 xml,这将删除除 /element 的第一个 hello 子节点之外的所有节点:

<xsl:template match="hello[not(current() = parent::element/hello[1])]" />

为什么这些不起作用? (假设第一个节点不是文本节点)

<xsl:template match="hello[not(self::hello/position() = 1)]" />
<xsl:template match="hello[not(./position() = 1)]" />

还是这个?

<xsl:template match="hello[not(self::hello[1])]" />

self轴选什么?为什么最后一个示例不等同于 not(hello[1])

首先,你这样说是错误的:

This deletes all the nodes except the first hello child of /element

事实是它删除了(如果这是正确的词)/element 的任何 hello 个子项,其值与其中第一个的值不同。例如,给定:

XML

<element>
    <hello>a</hello>
    <hello>b</hello>
    <hello>c</hello>
    <hello>a</hello>
</element>

模板:

<xsl:template match="hello[not(current() = parent::element/hello[1])]" />

将匹配第二个和第三个 hello 节点 - 但不匹配第一个 或第四个 .

现在,关于您的问题:在 XSLT 1.0 中,position() 不是有效的位置步骤 - 因此:

<xsl:template match="hello[not(self::hello/position() = 1)]" />

应该return一个错误。

在 XSLT 2.0 中,模式 hello[not(self::hello/position() = 1)] 将不匹配 any hello 元素 - 因为自轴上只有一个节点,因此它的位置总是 1.

同样:

<xsl:template match="hello[not(./position() = 1)]" />

在 XSLT 1.0 中无效。

在 XSLT 2.0 中,./position() 将始终 return 1,原因与以前相同:.self::node() 的缩写,并且只有一个这样的节点。

最后,这个模板:

<xsl:template match="hello[not(self::hello[1])]" />

正在寻找一个自身没有(第一个实例)的节点。当然,这样的节点是不可能存在的。

在“/”运算符的 RHS 上使用 position() 永远不会有用——在 XSLT 1.0 中,这是您问题上的标记,实际上是不允许的。

在 XSLT 2.0 中,表达式 X/position() 的结果是一个整数序列 1..count(X)。如果 LHS 是单例,如 self::E,则 count(X) 为 1,因此结果为单个整数 1.