如何根据节点与文档根的相对距离选择一组节点



我已经考虑这个问题很长一段时间了,但似乎找不到一个合理的解决方案:如何根据节点与文档根的相对距离来选择一组节点?

给定一个示例HTML片段,如已经用Nokogiri解析的那样:

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

假设我对这份文档唯一了解的是,我正在寻找的节点是:具有与CCD_ 2标签相同的相对距离和最高匹配量的一组CCD_。在上面的例子中,这意味着匹配<ol>内部的组,因为它具有与<body>具有相同距离的最高数量的节点。

你对如何解决这个问题有什么想法吗?

这是一个奇怪的需求/请求,但我会从以下内容开始:

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的"集合"功能,您应该能够准确地识别哪些节点位于同一父节点下。我不知道如何解决<li>节点不同的问题。

希望这些能给你一些工作思路。

相关内容

  • 没有找到相关文章

最新更新