如何选择包含文本的最小元素

时间:2017-03-17 19:48:14

标签: ruby-on-rails ruby css-selectors nokogiri

我正在使用Rails 5和Nokogiri。如何选择包含文本的最小元素?

我的页面上有这个元素:

select case userID
    case 1,2,3,4,5,6
       ' do something
end select

我想我可以选择它:

<td class="style35" style="font-size: medium; border: thin solid #000000">
                        Location</td>

相反,选择包含包含此元素的表的包装td:

doc.at('td:contains("Location")')

编写一个表达式选择包含我想要的文本的最小(最小的?)元素的正确方法是什么?

3 个答案:

答案 0 :(得分:0)

如果您使用at方法,则只返回第一个结果。

css方法将返回与CSS选择器匹配的所有元素,包括正确的td元素和围绕整个表的td元素。

如果你使用这样的东西,它会找到包含单词td的所有Location标签,然后它将存储未包裹在数组中另一个td标签的元素:< / p>

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

答案 1 :(得分:0)

如果您没有向我们提供最低限度的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 .style35td 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"

答案 2 :(得分:-1)

选择所有td元素,按内容长度排序并选择第一个元素。根据需要更改选择器。排序默认为升序。所以你先得到最小的元素。

doc.css('td').sort_by do |td_element|
  l.text.length
end.first