流行测验!我有一个包含多行且没有唯一标识符的表。识别唯一行的唯一方法是匹配超过两个值(1 following-sibling
和1 preceding-sibling
无法工作)。以下是样本
<tr>
<td>Map</td>
<td>First</td>
<td>Second</td>
<td>Third</td>
<td>A01</td>
<td><a href='test0'>Test 0</a></td>
</tr>
<tr>
<td>Map</td>
<td>First</td>
<td>Tenth</td>
<td>Third</td>
<td>A03</td>
<td><a href='test1'>Test 1</a></td>
</tr>
<tr>
<td>Map</td>
<td>Second</td>
<td>Fifth</td>
<td>Forth</td>
<td>A02</td>
<td><a href='test2'>Test 2</a></td>
</tr>
我需要Test 2
并且我有以下数据。
td[1]
,Map
td[2]
,Second
td[3]
,Fifth
td[4]
,Forth
td[5]
,A02
这是我尝试过的XPath:
//td/a[contains(., 'Test 2')][preceding-sibling::td[1][contains(., 'Map')] and td[2][contains(., 'Second')] and td[3][contains(., 'Fifth')] and td[4][contains(., 'Forth')] and td[5][contains(., 'A02')]]
我为此寻找解决方案而生气!非常感谢帮助!
答案 0 :(得分:2)
如果将谓词放在tr
...
//tr[td[1]='Map' and td[2]='Second' and td[3]='Fifth' and td[4]='Forth' and td[5]='A02']/td[6]/a
或
//tr[td[1]='Map'][td[2]='Second'][td[3]='Fifth'][td[4]='Forth'][td[5]='A02']/td[6]/a
原始尝试不起作用的原因是因为上下文为a
且a
根本没有任何前置兄弟。您需要执行../preceding-sibling::td
...
//a[../preceding-sibling::td[5]='Map' and ../preceding-sibling::td[4]='Second' and ../preceding-sibling::td[3]='Fifth' and ../preceding-sibling::td[2]='Forth' and ../preceding-sibling::td[1]='A02']
另请注意,使用前兄弟时,这些位置是向后的。
答案 1 :(得分:1)
获取包含一些子元素的元素:
tag[./child]
获取具有某个属性的子元素,该属性符合以下条件:[@id='someId']
或[contains(text(),'some text')]
:
tag[./child[condition]]
通过几个条件获取元素:
tag[condition1][condition2]
让我们将其收集到1个定位器中。所以要获得包含带文本的子元素的元素:
//tr[./td[text()='Map']]
所以要重复的模式是:[./td[text()='text']]
让我们添加一些其他必需的孩子:
//tr[./td[text()='Map']][./td[text()='Second']][./td[text()='Fifth']]
你可以轻松地创建一个java方法,这样可以将内部文本作为params并构建完整路径:
public static String getPath(String... innerText) {
StringBuilder path = new StringBuilder("//tr"); //before tr - table could be specified
Arrays.stream(innerText).forEach(
text -> path.append("[./td[text()='").append(text).append("']]")
);
return path.toString();
}
所以这里我们得到包含所需内部文本的tr。现在我们可以在其中搜索a
标记。只需添加到定位器的末尾://a
或者如果您需要文字://a/text()
结果是:
//tr[./td[text()='Map']][./td[text()='Second']][./td[text()='Fifth']]//a