<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])
?
首先,你说的是错误的:
这将删除除
/element
的第一个hello
子节点之外的所有节点
事实是,它删除了(如果这是正确的单词(/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
节点,但不匹配第一个或第四个。
现在,关于您的问题:在XSLT1.0中,position()
不是一个有效的定位步骤,因此:
<xsl:template match="hello[not(self::hello/position() = 1)]" />
应该返回一个错误。
在XSLT2.0中,模式hello[not(self::hello/position() = 1)]
将不匹配任何hello
元素,因为自轴上只有一个节点,因此其位置始终为1。
类似:
<xsl:template match="hello[not(./position() = 1)]" />
在XSLT 1.0中无效。
在XSLT2.0中,./position()
将始终返回1,原因与以前相同:.
是self::node()
的缩写,并且只有一个这样的节点。
最后,这个模板:
<xsl:template match="hello[not(self::hello[1])]" />
正在寻找一个本身没有(的第一个实例(的节点。当然,这样的节点是不可能存在的。
在"/"运算符的RHS上使用position((从来都没有用过——在XSLT1.0中,这是问题的标记,实际上是不允许的。
在XSLT2.0中,表达式X/position((的结果是一个整数序列1..count(X(。如果LHS是一个单例,比如self::E,那么count(X(是一个,所以结果是单个整数1。