如何使用 XPath 向后匹配最近的标签

How to match nearest tag backward with XPath

我有一个 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

我想从静态值 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']] 匹配外部 table 而不是内部 table。

在 XPath 中有像这样的 nearest backward match 表达式吗?

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

是的,//table[//td[text()='Foo']] 给出外部 table 作为第一个结果(不是唯一的结果),但是 //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中,您可以使用at_xpath代替上面表达式中的[1],如[=23] =]

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

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