从一组xpath中查找公共祖先?
说我有从一组xpath中查找公共祖先?,xpath,nokogiri,Xpath,Nokogiri,说我有 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”下面的函数共同祖先满足您的要求 require 'rubygems' require 'nokogiri' doc = Nokogiri::XML
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”下面的函数
共同祖先
满足您的要求
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>
需要“rubygems”
需要“nokogiri”
doc=Nokogiri::XML(数据)
def公共_祖先*元素
如果elements.empty返回nil?
元素地图!是否准备好数组
元素地图!是否为每个给定元素构建祖先数组
e[1]。在e[0]时取消移动e[0]。对?(:父项)和e[0]=e[0]。父项进行响应
e[1]
结束
#合并相应的祖先并找到所有祖先都相同的最后一个祖先
元素[0]。zip(*元素[1..-1])。选择{e | e.uniq.length==1}.flatte.last
结束
i=doc.xpath('/*[@id=“i”]')。首先
div=doc.xpath('/*[@id=“div”]')。首先
h1=doc.xpath('/*[@id=“h1”]')。首先
p公共祖先i,div,h1#=>给出了p元素
__结束__
要查找两个节点之间的共同祖先:
(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>
#接受节点对象或选择器字符串
类Nokogiri::XML::Element
def公共_祖先(*节点)
nodes=nodes.map do | node|
字符串===节点?self.document.at(节点):节点
结束
nodes.inject(self.祖先)do | common,node|
公共节点和节点
完
结束
结束
#用法:
node1.common_祖先(node2,“//foo/bar”)
# =>
试着给我们一个你想要解决的问题的大局图。