我有这样的HTML:
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
我希望从静态值Bar
获得更改值Foo
。
使用此代码,我可以获得该值。
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']]
答案 0 :(得分: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]
,您可以使用{/ 1}}
at_xpath
仅获取找到的第一个结果节点。也就是说,如果您实际上只打算找到一个节点,并且所需节点是文档顺序中的第一个节点。