2015-01-21 50 views
2

落后符合最近的标签我有一个HTML这样的:如何使用XPath

html =<<EOS 
<table><!-- outer table --> 
    <tr><td> 
    <table><!-- inner table 1 --> 
     <tr><td>Foo</td></tr> 
    </table> 
    <table><!-- inner table 2 --> 
     <tr><td>Bar</td></tr> 
    </table> 
    </td></tr> 
</table> 
EOS 

我想从一个静态值Foo得到一个变化值Bar

有了这段代码,我可以获得价值。

Nokogiri::HTML(html) 
doc.xpath("//table[tr/td[text()='Foo']]/following-sibling::table//td").text 

,我想改写这样的:

doc.xpath("//table[//td[text()='Foo']]/following-sibling::table//td").text 

但这码不起作用,因为//table[//td[text()='Foo']]匹配外部表不是内部表。

在XPath中是否有像这样的表达式nearest backward match

//table[(nearest match expression)td[text()='Foo']]

回答

1

是,//table[//td[text()='Foo']]给出外部表作为第一结果(不是唯一的结果),但仍然//table[//td[text()='Foo']]/following-sibling::table//td检索<td>Bar</td>

//table[//td[text()='Foo']]有问题的部分是在td前面//,因为它选择的所有后代td元素:

<table> 
    <tr> 
    <td>This is selected</td> 
    <td> 
     <table> 
     <tr> 
      <td>This is also selected</td> 
     </tr> 
     </table> 
    </td> 
    </tr> 
</table> 

你应该使用//仅微。我会用表达

//table[tr/td = 'Foo']/following-sibling::table[1]/tr/td 

编辑:如上表达建议的Phrogz,在引入nokogiri,而不是[1],您可以在

doc.at_xpath(//table[tr/td = 'Foo']/following-sibling::table/tr/td).text 

使用at_xpath为仅获取找到的第一个结果节点。也就是说,如果您实际上只打算找到一个节点,并且想要的节点是文档顺序中的第一个。

+0

使用'my_doc.at'或'my_doc.at_xpath'可以从XPath中删除'[1]',对吗? – Phrogz 2015-01-21 19:06:55

+0

@Phrogz可能是Ruby语法吗?这是什么意思? – 2015-01-21 19:08:07

+1

使用Nokogiri'at'和'at_xpath'方法将仅返回第一个匹配元素,而不是一组节点。 – Phrogz 2015-01-21 19:09:36