2009-09-28 1 views
1

내가 공통의 조상을 얻을 수있는 방법xpath 그룹에서 공통 조상을 찾았습니까?

html/body/span/div/p/h1/i/font 
html/body/span/div/div/div/div/table/tr/p/h1 
html/body/span/p/h1/b 
html/body/span/div 

이 있다고? 이 경우 기간에 의 공통 조상이 될 것 "글꼴, H1, B, DIV"common_ancestor 아래 당신이 원하는 것을 "범위"

+0

당신이 뭘 하려는지 : 여러 노드와 함께 작동

(node1.ancestors & node2.ancestors).first 

더 일반화 된 기능을? – Tomalak

+0

당신이 해결하고자하는 것을 크게 보여주십시오. – Javier

답변

3

두 노드 사이의 공통 조상을 찾는 방법은 다음과 같습니다

# accepts node objects or selector strings 
class Nokogiri::XML::Element 
    def common_ancestor(*nodes) 
    nodes = nodes.map do |node| 
     String === node ? self.document.at(node) : node 
    end 

    nodes.inject(self.ancestors) do |common, node| 
     common & node.ancestors 
    end.first 
    end 
end 

# usage: 

node1.common_ancestor(node2, '//foo/bar') 
# => <ancestor node> 
0

기능이 될 것입니다.

require 'rubygems' 
require 'nokogiri' 

doc = Nokogiri::XML(DATA) 

def common_ancestor *elements 
    return nil if elements.empty? 
    elements.map! do |e| [ e, [e] ] end #prepare array 
    elements.map! do |e| # build array of ancestors for each given element 
    e[1].unshift e[0] while e[0].respond_to?(:parent) and e[0] = e[0].parent 
    e[1] 
    end 
    # merge corresponding ancestors and find the last where all ancestors are the same 
    elements[0].zip(*elements[1..-1]).select { |e| e.uniq.length == 1 }.flatten.last 
end 

i = doc.xpath('//*[@id="i"]').first 
div = doc.xpath('//*[@id="div"]').first 
h1 = doc.xpath('//*[@id="h1"]').first 

p common_ancestor i, div, h1 # => gives the p element 

__END__ 
<html> 
    <body> 
    <span> 
     <p id="common-ancestor"> 
     <div> 
      <p><h1><i id="i"></i></h1></p> 
      <div id="div"></div> 
     </div> 
     <p> 
      <h1 id="h1"></h1> 
     </p> 
     <div></div> 
     </p> 
    </span> 
    </body> 
</html>