假设我正在查询xhtml文档,并且我想查询带有id='target'
的表后面的所有兄弟姐妹。此外,我既不想要第一个<table>
兄弟,也不想要这个特定元素的第一个<ol>
兄弟。这是我能想到的最好的:
//table[@id='target']/following-sibling::*[not(self::table[1]) and not(self::ol[1])]
然而,这应该没有返回任何结果。显然我不理解这方面的一些语法(我找不到一个好的信息来源)。如果有经验丰富的XPath语法的人能帮到我,我当然会感激不尽。另外,出于纯粹的学术目的,我很好奇上面的内容是什么。
更新:
请参阅LarsH的答案,解释为什么我的XPath无法正常工作,并看到Dimitre对已接受解决方案的回答。
答案 0 :(得分:14)
使用强>:
/table[@id='target']/following-sibling::*[not(self::table) and not(self::ol)]
|
/table[@id='target']/following-sibling::table[position() > 1]
|
/table[@id='target']/following-sibling::ol[position() > 1]
这将选择表格中不是table
且不是ol
的所有以下兄弟姐妹以及位置为2或更高且以下所有table
所有兄弟姐妹ol
位置为2或更大的兄弟姐妹。
这正是您想要的:所有以下兄弟姐妹,除了第一个table
后续兄弟姐妹和第一个ol
以下兄弟姐妹。
这是纯XPath 1.0 ,并且不使用任何XSLT函数。
答案 1 :(得分:2)
首先回答第二个问题:上面做的是选择以下既不是table
也不是ol
元素的兄弟姐妹。
原因如下:self::table[1]
选择上下文节点的self(如果它通过table
元素名称测试)并过滤以仅选择沿self :: axis的第一个节点。 self :: axis上最多有一个节点通过元素名称测试,因此[1]
是多余的。 self::table[1]
只要它是一个表元素就选择上下文节点,无论它在兄弟节点中的位置如何。因此,只要上下文节点是表元素,not(self::table[1])
就会返回false,无论它在兄弟节点中的位置如何。
同样适用于self::ol[1]
。
如何做你想做的事情:
@John Kugelman的答案几乎是正确的,但忽略了我们必须忽略兄弟元素table[@id='target']
之前和之后的事实。我不认为在纯XPath 1.0中正确执行是可能的。 您是否可以使用XPath 2.0?如果您在浏览器中工作,答案通常是否定的。
一些解决方法是:
//table[@id='target']
作为节点集,将其返回到主机环境(即XPath之外,例如在JavaScript中),循环通过该节点集;循环内部:通过XPath选择following-sibling::*
,遍历XPath之外的 ,并测试每个结果(在XPath之外)以查看它是第一个表还是ol。//table[@id='target']
作为节点集,将其返回到主机环境(即XPath之外,例如在JavaScript中),循环通过该节点集;在循环内:通过XPath选择generate-id(following-sibling::table[1])
和generate-id(following-sibling::ol[1])
,将这些值接收到JS变量t1id和o1id中,并使用'following-sibling::*[generate-id() != ' + t1id + ' and generate-id() != ' + o1id + ']'
形式为XPath表达式构造一个字符串。在XPath中选择该字符串,你就有了答案! :-P 更新:在XSLT 1.0中可以使用 解决方案 - 请参阅@ Dimitre's。
答案 2 :(得分:1)
当您使用self::
轴时,只会有一个节点,所以我相信self::*[1]
将始终为真。每个节点将成为其自己的self::
轴上的第一个(也是唯一的)节点。这意味着您的括号表达式等同于[not(self::table) and not(self::ol)]
,这意味着所有表格和列表都会被过滤掉。
我没有设置测试环境,但是我可能会做得更好:
/table[@id='target']/following-sibling::*
[not(self::table and not(preceding-sibling::table)) and
not(self::ol and not(preceding-sibling::ol))]
需要进行一些调整,但想法是过滤掉没有先前兄弟table
的{{1}}和没有前面的table
兄弟ol
s。