7

jQuery には、DOM ツリーをたどって一致する要素を探す、closest()と呼ばれるやや不適切な名前のメソッドがあります。たとえば、次の HTML があるとします。

<table src="foo">
  <tr>
    <td>Yay</td>
  </tr>
</table>

elementが に設定されていると仮定すると、次のよう<td>に の値を計算できます。src

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

テーブル要素またはその src 属性のいずれかが欠落している場合、それは「未定義」をきれいに返します。

Javascriptland でこれに慣れてきたので、Rubyland で Nokogiri に相当するものを見つけたいと思っていますが、私が思いついた最も近いものは、この明らかに非エレガントなハックです

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

空の配列で呼び出された場合、最初に nil が返されるため、3 進数が必要です。より良いアイデア?

4

3 に答える 3

12

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
于 2011-11-04T00:28:26.803 に答える
6

xpath を使用してこれを行うこともできます。

element.xpath('./ancestor::table[1]')
于 2011-11-04T00:40:39.773 に答える
3

src最も近いテーブルの祖先の属性が存在する場合は、それが必要ですか?XPathを介して存在する可能性のある要素を取得してから、Rubyを介して属性を取得する代わりに、XPathで直接属性を要求します。

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

属性またはnilのいずれかを取得します。

irb(main):001:0> require 'nokogiri'
#=> true

irb(main):002:0> xml = '<r><a/><table src="foo"><tr><td /></tr></table></r>'
#=> "<r><a/><table src=\"foo\"><tr><td /></tr></table></r>"

irb(main):003:0> doc = Nokogiri.XML(xml)
#=> #<Nokogiri::XML::Document:0x195f66c name="document" children=…

irb(main):004:0> doc.at('td').at_xpath( './ancestor::table[1]/@src' )
#=> #<Nokogiri::XML::Attr:0x195f1bc name="src" value="foo">

irb(main):005:0> doc.at('a').at_xpath( './ancestor::table[1]/@src' )
#=> nil
于 2011-11-04T15:56:05.360 に答える