您可以调用Nokogiri::XML::Node#ancestors.size
来查看节点嵌套的深度。但有没有办法确定一个节点的嵌套最深的子节点的嵌套程度有多深?
或者,如何找到从节点下降的所有叶节点?
答案 0 :(得分:1)
你可以打电话 Nokogiri :: XML :: Node#ancestors.size to 看看节点嵌套的深度。但 有没有办法确定有多深 嵌套最嵌套的孩子 节点是?
使用强>:
count(ancestor::node())
此表达式表示上下文(当前)节点在文档层次结构中具有的祖先数。
要找到“嵌套最深的子级”的嵌套级别,必须首先确定所有“叶子”节点:
descendant-or-self::node()[not(node())]
并使用上面的XPath表达式获得每个嵌套级别。
然后必须计算最大嵌套级别(生成的所有数字的最大值),并且使用纯XPath 1.0无法进行最后一次计算。
可以在单个XPath 2.0表达式中表达:
max(for $leaf in /descendant-or-self::node()[not(node())],
$depth in count($leaf/ancestor::node())
return
$depth
)
答案 1 :(得分:1)
下面的代码为Monkey-patches Nokogiri::XML::Node
以获得乐趣,但当然,如果您愿意,可以将它们作为单独的方法提取节点参数。 (只有height
方法是您问题的一部分,但我认为deepest_leaves
方法可能很有趣。)
require 'nokogiri'
class Nokogiri::XML::Node
def depth
ancestors.size
# The following is ~10x slower: xpath('count(ancestor::node())').to_i
end
def leaves
xpath('.//*[not(*)]').to_a
end
def height
tallest = leaves.map{ |leaf| leaf.depth }.max
tallest ? tallest - depth : 0
end
def deepest_leaves
by_height = leaves.group_by{ |leaf| leaf.depth }
by_height[ by_height.keys.max ]
end
end
doc = Nokogiri::XML "<root>
<a1>
<b1></b1>
<b2><c1><d1 /><d2><e1 /><e2 /></d2></c1><c2><d3><e3/></d3></c2></b2>
</a1>
<a2><b><c><d><e><f /></e></d></c></b></a2>
</root>"
a1 = doc.at_xpath('//a1')
p a1.height #=> 4
p a1.deepest_leaves.map(&:name) #=> ["e1", "e2", "e3"]
p a1.leaves.map(&:name) #=> ["b1", "d1", "e1", "e2", "e3"]
修改:简单地回答 问题,而不是将其包装在可重复使用的部分中:
p a1.xpath('.//*[not(*)]').map{ |n| n.ancestors.size }.max - a1.ancestors.size