我想在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中查找,因为我认为它实际上是这样做的。
有人可以向我解释在选定的节点/节点集中搜索和导航的原则,而不是整个文档吗?在这种情况下,沿着已知路径行进会更好,但我也不知道如何做到这一点。
答案 0 :(得分:3)
您的第二个XPath表达式//td[@class="left"]
以//
开头。这意味着在匹配节点时从整个文档的根开始。你想要的是从当前节点开始。为此,请使用点.//
:
d.xpath('.//td[@class="left"]')