Xml XPath-除第一个特定元素外的所有后续同级元素
假设我正在查询一个xhtml文档,我想用Xml XPath-除第一个特定元素外的所有后续同级元素,xml,xhtml,xpath,Xml,Xhtml,Xpath,假设我正在查询一个xhtml文档,我想用id='target'查询表后面的所有同级。另外,我既不想要这个特定元素的第一个同级,也不想要这个特定元素的第一个同级。以下是我能想到的最好的: //table[@id='target']/following-sibling::*[not(self::table[1]) and not(self::ol[1])] 然而,这并没有在应该的时候返回任何结果。显然,我不理解其中的一些语法(我找不到好的信息来源)。如果有更熟悉XPath语法的人能帮我一把,我将不
id='target'
查询表后面的所有同级。另外,我既不想要这个特定元素的第一个
同级,也不想要这个特定元素的第一个
同级。以下是我能想到的最好的:
//table[@id='target']/following-sibling::*[not(self::table[1]) and not(self::ol[1])]
然而,这并没有在应该的时候返回任何结果。显然,我不理解其中的一些语法(我找不到好的信息来源)。如果有更熟悉XPath语法的人能帮我一把,我将不胜感激。此外,出于纯粹的学术目的,我想知道上面的内容实际上在做什么
更新:请参阅LarsH的答案以了解我的XPath为什么不工作,并参阅Dimitre的答案以了解可接受的解决方案。使用
self::
轴时,只会有一个节点,因此我相信self::*[1]
将始终是正确的。每个节点都将成为其自身self::
轴上的第一个(也是唯一一个)节点。这意味着括号中的表达式相当于[非(self::table)和非(self::ol)]
,这意味着所有的表和列表都会被过滤掉
我没有设置测试环境,但我想这可能会更好:
/table[@id='target']/following-sibling::*
[not(self::table and not(preceding-sibling::table)) and
not(self::ol and not(preceding-sibling::ol))]
它需要一些调整,但其想法是过滤掉前面没有同级表的
表
s,而ol
s没有前面的同级ol
s。首先回答第二个问题:上面所做的是选择以下既不是表
也不是ol
元素的同级
原因如下:self::table[1]
选择上下文节点的self(如果它通过了table
元素名测试),并过滤以仅选择self::轴上的第一个节点。self::axis上最多有一个节点通过了元素名测试,因此[1]
是冗余的self::table[1]
选择上下文节点,只要它是表元素,而不管它在同级元素中的位置如何。因此not(self::table[1])
在上下文节点是表元素时返回false,而不管它在同级元素中的位置如何
类似地,对于self::ol[1]
如何做你想做的事情:
@John Kugelman的回答几乎是正确的,但忽略了一个事实,即我们必须在包含表[@id='target']
之前忽略兄弟元素。我认为不可能在纯XPath1.0中正确执行您是否可以使用XPath 2.0?如果您在浏览器中工作,答案通常是否定的
一些解决办法是:
- 通过基于其他一些基础(例如属性)进行筛选,跳过第一个后续表同级和第一个后续ol同级李>
- 选择
作为节点集,将其返回到主机环境(即在XPath之外,例如在JavaScript中),循环通过该节点集;在循环内部:选择//table[@id='target']
通过XPath,在XPath之外的中迭代,并测试每个结果(XPath之外)以查看它是第一个表还是ol以下同级::*
- 选择
作为节点集,将其返回到主机环境(即在XPath之外,例如在JavaScript中),循环通过该节点集;在循环内部:通过XPath选择//table[@id='target']
和generate id(以下是sibling::table[1])
,将这些值接收到JS变量t1id和o1id中,并使用generate id(以下是sibling::ol[1])
。在XPath中选择该字符串,您就有了答案!:-p“following-sibling::*[generate-id()!=”+t1id+”和generate-id()的形式为XPath表达式构造一个字符串!='+o1id+']'
/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
同级,以及位置2或更大的所有以下ol
同级
这正是您想要的:除第一个表
后面的兄弟姐妹和第一个ol
后面的兄弟姐妹外,所有后面的兄弟姐妹
这是纯XPath 1.0,不使用任何XSLT函数。正如我在回答中所指出的,该解决方案忽略了一个事实,即当您测试以下同级以查看哪个是
[1]
时,目标表不应算作前面的同级。此外,前面的同级测试必须忽略目标表之前的任何表或ol元素。好问题,+1。请参阅我的答案,了解一个选择所需节点的XPath表达式。:)@约翰·库格曼:看看我的amswer,它提供了一个纯而不太复杂的XPath 1.0解决方案。感谢您对我尝试的查询失败原因的精彩解释。我最终使用了Dimitre的XPath来解决这个问题。这正是我所寻找的优雅的解决方案,实际上非常简单。我从来没有想过要得到三个相互排斥的集合的并集,其中包含除这两个元素之外的所有元素。非常感谢。啊,应该好好想想。:-)我在尝试工会的解决方案,但没能实现。尽管输入错误:根据最初的问题,/
而不是/
是在表
之前需要的。呵呵,出于某种原因,我决定使用联合解决方案是不好的,并特别避免使用它+1感谢你没有像我一样愚蠢。:-)