在Nokogiri中限制XPath的搜索范围

时间:2015-10-21 09:34:20

标签: ruby-on-rails ruby xpath nokogiri

我想在NodeSet中找到NodeSet中的特定标签,但是当我使用XPath时,它返回整个NodeSet的结果。

我试图得到类似的东西:

{ "head1" => "Volume 1", "head2" => "Volume 2" }

来自这个HTML:

<h2 class="header">
  <a class="header" >head1</a>
</h2>
<table class="volume_description_header" cellspacing="0">
  <tbody>
    <tr>
      <td class="left">Volume 1</td>
    </tr>
  </tbody>
</table>
<h2 class="header">
  <a class="header" >head2</a>
</h2>
<table class="volume_description_header" cellspacing="0">
  <tbody>
    <tr>
      <td class="left">Volume 2</td>
    </tr>
  </tbody>
</table>

到目前为止,我已尝试过:

require 'nokogiri'
a = File.open("code-above.html") { |f| Nokogiri::HTML(f) }
h = a.xpath('//h2[@class="header"]')
puts h.map { |e| e.next.next }[0].xpath('//td[@class="left"]')

但有了这个,我得到了:

<td class="left ">Volume 1</td>
<td class="left ">Volume 2</td>

我只期待第一个。

我已经尝试在块内部执行XPath但是这给了我两次相同的结果。

我查了一下

puts h.map { |e| e.next.next }[0]

评估到第一个节点,所以我不明白为什么XPath会在整个NodeSet或整个Nokogiri :: Document中查找,因为我认为它实际上是这样做的。

有人可以向我解释在选定的节点/节点集中搜索和导航的原则,而不是整个文档吗?在这种情况下,沿着已知路径行进会更好,但我也不知道如何做到这一点。

1 个答案:

答案 0 :(得分:3)

您的第二个XPath表达式//td[@class="left"]//开头。这意味着在匹配节点时从整个文档的根开始。你想要的是从当前节点开始。为此,请使用点.//

开始表达
d.xpath('.//td[@class="left"]')