2017-07-13 168 views
0

流行测验!我有一个包含多行且没有唯一标识符的表格。唯一标识唯一行的方法是匹配两个以上的值(1 following-sibling和1 preceding-sibling将不起作用)。以下是一个样本xpath中的多个跟随兄弟姐妹或兄弟姐妹前

<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

显示你试过什么 – Andersson

+2

他说他试过气。 – kjhughes

+1

解决当前问题的奇怪方法 – Andersson

回答

1

获取包含一些子元素元素:[@id='someId'][contains(text(),'some text')]

tag[./child[condition]] 

几个获得元素

tag[./child] 

有孩子满足像条件的一些属性来获得元素条件:

tag[condition1][condition2] 

让收集到1个定位器中。因此,要获得包含子文本元素:

//tr[./td[text()='Map']] 

如此重复的模式是:[./td[text()='text']]

让我们添加一些其他需要的孩子:

//tr[./td[text()='Map']][./td[text()='Second']][./td[text()='Fifth']] 

您可以轻松地创建,让我们说,java的方法,这将只获得内部文本作为参数,并将构建完整路径:

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 
+0

我的模式比这个更长:'// tr [td ='text1'] ... [td ='textN']'由Daniel Haley提供,对我们来说更好,简称之一) –

+0

我喜欢这个解释。谢谢你节省我的时间。像魅力一样工作! – user3287400

1

如果你把谓词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 

的原因,您原来的尝试没有成功是因为背景是aa没有任何先行兄弟姐妹都没有。使用前同辈时,您需要做的../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'] 

另外还要注意,位置是倒退。

+0

这个答案与我的相似,但//tr[td='text1']...[td='textN']是我用的较短的模式=)做得好 –

+0

@ VitaliyMoskalyuk-谢谢。多谓词版本比在单个谓词中使用“and”更短。我也添加了该版本。另外,我只包含位置谓词,因为它们包含在原始问题中,所以我认为它们很重要。 –