如何将最近的标记向后与XPath匹配

时间:2015-01-21 09:22:34

标签: html ruby xpath nokogiri

我有这样的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']]

1 个答案:

答案 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

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