Nokogiri相当于jQuery nearest()方法,用于在树中查找第一个匹配的祖先

jQuery有一个可爱的,有点错误的名为nearest()的方法,它在DOM树中寻找匹配的元素。 例如,如果我有这个HTML:

Yay

假设element设置为

,那么我可以像这样计算src的值:

 element.closest('table')['src'] 

如果缺少表元素或其src属性,那将彻底返回“undefined”。

在Javascriptland中习惯了这个,我很想在Rubyland中找到与Nokogiri相同的东西,但是我能够想出的最接近的是使用祖先()的这种明显不优雅的黑客攻击:

 ancestors = element.ancestors('table') src = ancestors.any? ? first['src'] : nil 

需要三元组,因为如果在空数组上调用,则返回nil。 好主意?

你可以first调用一个空数组,问题是它会返回nil并且你不能说nil['src']而不会感到悲伤。 你可以这样做:

 src = (element.ancestors('table').first || { })['src'] 

如果你在Rails中,你可以try使用:

 src = element.ancestors('table').first.try(:fetch, 'src') 

如果你做了很多这样的事情,那么在方法中隐藏丑陋:

 def closest_attr_from(e, selector, attr) a = e.closest(selector) a ? a[attr] : nil end 

然后

 src = closest_attr_from(element, 'table', 'src') 

您也可以将其修改为Nokogiri :: XML :: Node(但我不推荐它):

 class Nokogiri::XML::Node def closest(selector) ancestors(selector).first end def closest_attr(selector, attr) a = closest(selector) a ? a[attr] : nil end end 

您也可以使用xpath执行此操作:

 element.xpath('./ancestor::table[1]') 

你想要最近的表祖先的src属性,如果它存在? 而不是通过XPath获取可能存在的元素,然后可能通过Ruby获取属性,而是直接在XPath中请求属性:

 ./ancestor::table[1]/@src 

您将获得属性或nil:

 irb(main):001:0> require 'nokogiri' #=> true irb(main):002:0> xml = '
' #=> "
" irb(main):003:0> doc = Nokogiri.XML(xml) #=> # doc.at('td').at_xpath( './ancestor::table[1]/@src' ) #=> # irb(main):005:0> doc.at('a').at_xpath( './ancestor::table[1]/@src' ) #=> nil