как найти все ссылки на одной глубине с общим ближайшим предком с нокогири - PullRequest
1 голос
/ 12 января 2012
d=<<"EOM"
<ul>
  <li><a id=t href="t">a</a></li>
  <li><a id=b href="b">b</a></li>
  <li>
    <ul>
      <li><a href="inner">don't want inner</a></li>
      <li><a href="inner">don't want inner</a></li>
    </ul>
  </li>
  <li><a id=c href="c">c</a></li>
</ul>
<ul>
  <li><a href="d">don't want</a></li>
</ul>
EOM

doc = Nokogiri.HTML(d)
t = doc.css("#t")[0]

как я могу получить все hrefs, которые имеют одинаковые внешний контейнер как "т" и в то же глубина как "т"? в этом случае я бы хотел только hrefs t, b, c. они не всегда будут в ul, просто используя это как пример.

Ответы [ 3 ]

1 голос
/ 13 января 2012

Если вы знаете, что идентификаторы будут согласованы:

puts doc.search('#t, #b, #c').map{ |n| n['href'] }

Если вы не знаете, какими они будут, то XPath может доставить вас туда:

doc.search('//*[@id="t"]/../../*/*[@id]').to_html
=> "<a id=\"t\" href=\"t\">a</a><a id=\"b\" href=\"b\">b</a><a id=\"c\" href=\"c\">c</a>"

doc.search('//*[@id="t"]/../../*/*[@id]').map{ |n| n['href'] }
=> ["t", "b", "c"]

Это означает, что "найдите узел с идентификатором 't', затем вернитесь на два уровня назад и посмотрите вниз, найдя узлы с заполненными атрибутами id".

1 голос
/ 12 января 2012

Чтобы получить все теги с тем же «дедушкой и бабушкой», что вы могли бы сделать:

doc.css('a').select{|a| a.parent.parent == t.parent.parent}

Чтобы получить их hrefs:

doc.css('a').select{|a| a.parent.parent == t.parent.parent}.map{|a| a[:href]}
0 голосов
/ 12 января 2012

Спасибо @ pguardiario

Родительский узел может быть на любом уровне, поэтому я изменил ваш код следующим образом:

 t = doc.css("#a")[0]
 r = []
 p = t.parent
 x = 0
 while true
   break if p.node_name == "body" || p.node_name == "html"
   x += 1
   r = doc.css('a').select{|a| 
     m = a
     x.times { m = m.parent }
     m  == p
     } 
   break if r.length > 1
   p = p.parent
 end
 pp r.length

Я уверен, что есть лучший способ, чем эта грубая силаспособ.

...