【问题标题】:Get child nodes with the same name as parent获取与父节点同名的子节点
【发布时间】:2012-06-02 11:24:03
【问题描述】:

我需要为父节点解析所有子节点,但是子节点与父节点具有相同的名称:

<div>
  <img></img>
  <div>
    <img></img>
  </div>
  <img></img>
</div>

我在 Ruby 中使用 Nokogiri,但是当我从第一个 div 节点执行 children() 时,解析在第一个 div 标记处过早结束。有什么解决方法吗?

【问题讨论】:

  • 能否请您展示一些您正在使用的 Ruby 代码或 xpath 选择器以及您的执行期望。
  • 看起来像一个简单的 CSS (node.css("div")) 或 XPath (node.xpath(".//div")) 选择器应该可以解决问题。
  • 我不明白您想要从您提供的示例 XML 和您描述的内容中得到什么。这里只有两种节点——divimg——你的描述都没有意义。 img 节点没有子节点,所以它们不在了。最上面的div确实有一个孩子div,但是你说“解析在第一个div过早结束”……但是只有一个其他div
  • 我需要我的解析器抓取我显示的所有节点。它过早结束,因为它从顶部 div 标签开始,当它到达第一个关闭 div 标签时,解析结束。它应该一直到最后一个结束 div 标签
  • @user1371011 这仍然不清楚。 Nokogiri 解析文档会创建一个包含所有节点的 DOM。然后你就可以选择或者遍历你需要的节点了。

标签: ruby nokogiri


【解决方案1】:

我几乎不想这么说,但这听起来像是遍历的另一个好案例:

require 'nokogiri'
html = <<EOF
<div>
  <img></img>
  <div>
    <img></img>
  </div>
  <img></img>
</div>
EOF

doc = Nokogiri::HTML html
doc.root.traverse do |node|
  if node.parent.name == node.name
    puts node
  end
end

【讨论】:

    【解决方案2】:

    假设您有一个起始节点并希望所有子节点具有相同的名称,这里有一些辅助方法的选项:

    # Using Ruby to Filter
    def same_kind_children(node)
      node.element_children.select{ |n| n.name==node.name }
    end
    
    # Using XPath to Filter
    def same_kind_children(node)
      node.xpath(node.name)
    end
    
    # Descendants instead of Children
    def same_kind_descendants(node)
      node.xpath(".//#{node.name}")
    end
    

    如果您心中有一种特定类型的节点,并希望找到该类型的每个具有相同类型父节点的节点:

    divs_in_divs = doc.xpath('div/div')
    

    虽然看起来不太可能,但如果您没有记住特定的起始节点或节点名称,但想要找到与其父节点同名的所有节点,您可以这样做:

    same_kind_nested = doc.xpath('//*').select{ |node| node.name==node.parent.name }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多