我想在 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/