我有以下html代码段:
<table>
<tr>
<td class="foo">a</td>
<td class="bar">1</td>
<td class="bar">2</td>
<td class="foo">b</td>
<td class="bar">3</td>
<td class="bar">4</td>
<td class="bar">5</td>
<td class="foo">c</td>
<td class="bar">6</td>
<td class="bar">7</td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)
我正在寻找一个XPath 1.0表达式,它从一个.foo元素开始,并.bar在下一个元素之前选择所有后续.foo元素.
例如:我开始a并且只想选择1和2.
或者我开始b并想要选择3,4和5.
背景:我必须为此方法找到一个XPath表达式(使用Java和Selenium):
public List<WebElement> bar(WebElement foo) {
return foo.findElements(By.xpath("./following-sibling::td[@class='bar']..."));
}
Run Code Online (Sandbox Code Playgroud)
有办法解决问题吗?
表达式应该适用于所有.foo元素,而不使用任何外部变量.
谢谢你的帮助!
更新:这些特殊情况显然没有解决方案.但是如果您的限制较少,则提供的表达式可以完美地运行.
好问题!
根据输入,以下表达式将为您提供1..2,3..5或6..7X + 1,其中X是您想要的集合(2 给出 1-2,3 给出 3-.5 等)。在示例中,我选择第三组,因此它具有[4]:
/table/tr[1]
/td[not(@class = 'foo')]
[
generate-id(../td[@class='foo'][4])
= generate-id(
preceding-sibling::td[@class='foo'][1]
/following-sibling::td[@class='foo'][1])
]
Run Code Online (Sandbox Code Playgroud)
该表达式 (imnsho) 的优点在于,您可以按给定的集合进行索引(而不是按相对位置进行索引),并且只有一处需要更新表达式。如果您想要第六组,只需输入[7]。
此表达式适用于任何有兄弟节点的情况,即您需要具有相同需求的任意两个节点之间的兄弟节点 ( @class = 'foo')。我将更新并解释。
将表达式中的替换[4]为您需要的任何设置,再加上 1。在 oXygen 中,上面的表达式显示了以下选择:
/table/tr[1]
Run Code Online (Sandbox Code Playgroud)
选择第一个tr.
/td[not(@class = 'foo')]
Run Code Online (Sandbox Code Playgroud)
选择任何td不foo
generate-id(../td[@class='foo'][4])
Run Code Online (Sandbox Code Playgroud)
获取 xth 的标识foo,在本例中,选择空并返回空。在所有其他情况下,它将返回我们感兴趣的下一个的身份foo。
generate-id(
preceding-sibling::td[@class='foo'][1]
/following-sibling::td[@class='foo'][1])
Run Code Online (Sandbox Code Playgroud)
获取第一个前一个的标识foo(从任何非 foo 元素开始向后计数),并从那里开始获取第一个后一个foo. 在节点 的情况下7,这会返回虚无的标识,从而导致true我们的示例情况为[4]。在节点的情况下3,这将导致c,它不等于无,从而导致false。
如果该示例具有值,则最后一位将返回节点和 的[2]节点,这等于返回的标识。对于节点b12../td[@class='foo'][2]true4等7,这将返回false。
我们可以generate-id用 count-preceding-sibling 函数替换该函数。由于两个节点之前的兄弟节点数量foo各不相同,因此这可以作为以下方法的替代方案:generate-id。
不过,现在它开始变得像 GSerg 的答案一样实用:
/table/tr[1]
/td[not(@class = 'foo')]
[
count(../td[@class='foo'][4]/preceding-sibling::*)
= count(
preceding-sibling::td[@class='foo'][1]
/following-sibling::td[@class='foo'][1]/preceding-sibling::*)
]
Run Code Online (Sandbox Code Playgroud)
应用相同的“索引”方法。我[4]上面写的地方,将其替换为您感兴趣的第n + 1个交叉点位置。