我正在使用 Rails 5 和 Nokogiri。 如何选择包含文本的最小元素?
我的页面上有这个元素:
<td class="style35" style="font-size: medium; border: thin solid #000000">
Location</td>
我想我可以使用以下方法选择它:
doc.at('td:contains("Location")')
而是选择包含包含此元素的表的包装 td:
<td><span class="myClass"><table> ....
编写一个表达式的正确方法是什么,该表达式选择包含我想要的文本的最小(最最小?(元素?
如果使用 at
方法,它只会返回第一个结果。
css
方法将返回与 CSS 选择器匹配的所有元素,包括正确的 td
元素和环绕整个表的 td
元素。
如果你使用这样的东西,它会找到所有td
标签,包含单词 Location
,然后它将把未包裹在另一个 td 标签上的元素存储在数组中:
td_with_no_child_and_have_location = []
doc.css("td:contains('Location')").each do |td_element|
if td_element.css("td").empty?
td_with_no_child_and_have_location << td_element
end
end
first_td = td_with_no_child_and_have_location.first
如果您不向我们提供最少的 HTML,就很难帮助您。我尝试重新创建它,但是 YMMV:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html><body><table><tr>
<td><span class="myClass"><table><tr>
<td class="style35" style="font-size: medium; border: thin solid #000000">
Location</td>
</tr></table></td></tr></table></html>
EOT
doc.at('.myClass td.style35').text # => "n Location"
如果所需的标记嵌入在另一个表中,则利用其他一些特征来帮助您导航,例如类信息。
在这种情况下,使用 at
应该会有所帮助,因为通常表格的标题将位于包含第一个单元格的第一行中。 at
相当于search('some selector').first
。
上面的选择器甚至可以写成.myCLass .style35
或td td
,这将在另一个td中找到td。将其与at
结合起来,您将获得第一次这样的情况:
doc.at('.myClass td.style35').text # => "n Location"
doc.at('.myClass .style35').text # => "n Location"
doc.at('td td').text # => "n Location"
选择所有td
元素,按内容长度排序,然后选择第一个元素。根据需要更改选择器。默认情况下,排序是升序的。所以你首先得到最小的元素。
doc.css('td').sort_by do |td_element|
l.text.length
end.first