从一组的XPath找到共同的祖先?(finding common ancestor from a g

2019-07-19 20:07发布

说我有

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,格”将是“跨度”

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


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


文章来源: finding common ancestor from a group of xpath?