ruby-on-rails - 限制 Nokogiri 中 XPath 的搜索范围

标签 ruby-on-rails ruby xpath nokogiri

我想在 NodeSet 中的 Node 中查找特定标签,但是当我使用 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>

我只期待第一个。

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

我检查过

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

计算第一个节点,所以我不明白为什么 XPath 在整个 NodeSet 甚至整个 Nokogiri::Document 中查找,因为我认为这就是它实际所做的。

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

最佳答案

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

d.xpath('.//td[@class="left"]')

关于ruby-on-rails - 限制 Nokogiri 中 XPath 的搜索范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33255703/

相关文章:

ruby-on-rails - database.yml 文件配置和 postgres - rake db :drop db:create db:migrate

ruby-on-rails - rails : How to store mailer password safely?

ruby-on-rails - 从 Rails Controller 访问 current_user 设计方法

ruby - 如何使用反射获取参数名称

html - 没有特定类后代的所有元素的 XPath?

python - module._init_() 最多接受 2 个参数(给定 3 个)(scrapy 教程 w/xpath)

ruby-on-rails - 无法安装 RMagick 2.16.0

ruby-on-rails - Ruby on Rails 安装 - Fedora 7

ruby - 系统方法的任意数量的参数

html - 使用 xpathSApply 的相同代码搜索多个路径