如何找到相同深度的所有链接与共同最近的祖先与nokogiri

时间:2012-01-12 07:26:57

标签: ruby dom nokogiri

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]

我怎样才能获得具有相同功能的所有href 外容器为“t”并且是相同的 深度为“t”?在这种情况下,我只想要 hrefs t,b,c。 这些并不总是在ul中,只是使用 以此为例。

3 个答案:

答案 0 :(得分:1)

要获得与您所做的相同“祖父母”的所有标签:

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]}

答案 1 :(得分:1)

如果您知道ID将保持一致:

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"]

这意味着“找到ID为't'的节点,然后备份两个级别,然后向下查找具有填充的id属性的节点”。

答案 2 :(得分:0)

谢谢@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

我确信有比这种蛮力方法更好的方法。