【问题标题】:finding common ancestor from a group of xpath?从一组 xpath 中找到共同的祖先?
【发布时间】:2009-09-30 20:16:30
【问题描述】:

说我有

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

如何获得共同祖先?在这种情况下 span 将是 "font, h1, b, div" 的共同祖先将是 "span"

【问题讨论】:

  • 尝试向我们展示您要解决的问题。

标签: xpath nokogiri


【解决方案1】:

在两个节点之间寻找共同的祖先:

(node1.ancestors & node2.ancestors).first

一个更通用的函数,适用于多个节点:

# 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>

【讨论】:

    【解决方案2】:

    下面的函数common_ancestor 做你想做的事。

    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>
    

    【讨论】:

      猜你喜欢
      • 2011-09-04
      • 2018-07-18
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      • 1970-01-01
      • 2014-03-19
      • 1970-01-01
      • 2011-04-21
      相关资源
      最近更新 更多