我一直在考虑这个问题很长一段时间,但我似乎无法找到一个合理的解决方案:如何根据它们与文档根目录的相对距离来选择一组节点?
给出一个像Nokogiri一样解析的样本HTML片段:
<body>
<nav>
<ol>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ol>
</nav>
<ul>
<li><a href="#">Feedback</a></li>
<li><a href="#">Follow us</a></li>
</ul>
</body>
假设我对此文档的唯一了解,那就是我要查找的节点是:
一组<a>
个与<body>
标记具有相同距离且匹配量最高的标记。在上面的示例中,这意味着匹配<ol>
内的组,因为它具有与<body>
具有相同距离的最大节点数。
关于如何解决这个问题的任何想法?
答案 0 :(得分:0)
这是一个奇怪的需求/请求,但我从这开始:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<body>
<nav>
<ol>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ol>
</nav>
<ul>
<li><a href="#">Feedback</a></li>
<li><a href="#">Follow us</a></li>
</ul>
</body>
EOT
a_tags = doc.search('a')
.group_by{ |n| n.path.split('/').count }
.max_by{ |c, n| c }
.last
a_tags
# => [#(Element:0x3fe3a6012a60 {
# name = "a",
# attributes = [ #(Attr:0x3fe3a6098750 { name = "href", value = "#" })],
# children = [ #(Text "Home")]
# }),
# #(Element:0x3fe3a6012830 {
# name = "a",
# attributes = [ #(Attr:0x3fe3a6096914 { name = "href", value = "#" })],
# children = [ #(Text "About")]
# }),
# #(Element:0x3fe3a601240c {
# name = "a",
# attributes = [ #(Attr:0x3fe3a6070ef8 { name = "href", value = "#" })],
# children = [ #(Text "Contact")]
# })]
a_tags
中的最终结果是与根相等距离的节点数组。
从那以后我尝试了:
a_tags = doc.search('a').group_by{ |n| n.path.gsub(/\[\d+\]/, '') }.max_by{ |p, n| n.size }
# => ["/html/body/nav/ol/li/a",
# [#(Element:0x3ff6f10d2c08 {
# name = "a",
# attributes = [ #(Attr:0x3ff6f10d1cf4 { name = "href", value = "#" })],
# children = [ #(Text "Home")]
# }),
# #(Element:0x3ff6f10d2b18 {
# name = "a",
# attributes = [ #(Attr:0x3ff6f10cc254 { name = "href", value = "#" })],
# children = [ #(Text "About")]
# }),
# #(Element:0x3ff6f10d2a8c {
# name = "a",
# attributes = [ #(Attr:0x3ff6f10c3b2c { name = "href", value = "#" })],
# children = [ #(Text "Contact")]
# })]]
返回一个由CSS路径(删除了索引值)和其下的节点列表组成的数组。我并不完全满意使用CSS路径来识别聚集的目标标签。
可以从节点向后走到文档的根目录,并将这些节点添加到数组中。然后,使用Array&#34; set&#34;您应该能够准确识别哪些节点位于相同的父节点下。我不确定如何处理<li>
节点不同的事实。
希望那些应该给你一些想法。