【问题标题】:Nokogiri: Searching for <div> using XPathNokogiri:使用 XPath 搜索 <div>
【发布时间】:2009-03-16 11:03:22
【问题描述】:

我使用 Nokogiri (Rubygem) css 搜索在我的 html 中查找某些 &lt;div&gt;。看起来 Nokogiri 的 css 搜索不喜欢正则表达式。我想切换到 Nokogiri 的 xpath 搜索,因为这似乎支持搜索字符串中的正则表达式。

如何在 xpath 搜索中实现下面提到的(伪)css 搜索?

require 'rubygems'
require 'nokogiri'

value = Nokogiri::HTML.parse(<<-HTML_END)
  "<html>
    <body>
      <p id='para-1'>A</p>
      <p id='para-22'>B</p>
      <h1>Bla</h1>
      <p id='para-3'>C</p>
      <p id='para-4'>D</p>
      <div class="foo" id="eq-1_bl-1">
        <p id='para-5'>3</p>
      </div>
    </body>
  </html>"
HTML_END

# my_block is given
my_bl = "1"
# my_eq corresponds to this regex
my_eq = "\/[0-9]+\/"

# FIXME The following line should be changed to an xpath search.
if my_div = value.css("div#eq-#{my_eq}_bl-#{my_bl}.foo").first
  # doing some stuff with the <p> inside the div
end

【问题讨论】:

    标签: ruby-on-rails ruby regex xpath nokogiri


    【解决方案1】:

    Mike Dalessio(Nokogiri 核心开发人员的一半)在#nokogiri(irc.freenode.net)上给了我一个答案。看起来 Nokogiri CSS 和 XPath 搜索都不支持正则表达式匹配。这是他关于如何使用 Nokogiri 搜索正则表达式的解决方案:

    require 'rubygems'
    require 'nokogiri'
    
    value = Nokogiri::HTML.parse(<<-HTML_END)
      "<html>
        <body>
          <p id='para-1'>A</p>
          <p id='para-22'>B</p>
          <h1>Bla</h1>
          <p id='para-3'>C</p>
          <p id='para-4'>D</p>
          <div class="foo" id="eq-1_bl-1">
            <p id='para-5'>3</p>
          </div>
          <div class="bar" id="eq-1_bl-1">
            <p id='para-5'>3</p>
          </div>
        </body>
      </html>"
    HTML_END
    
    # my_block is given
    my_bl = "1"
    # my_eq corresponds to this regex
    my_eq = "[0-9]+"
    # full regex to search for in node ids
    full_regex = %r(eq-#{my_eq}_bl-#{my_bl})
    
    filter_by_id = Class.new do
      attr_accessor :matches
    
      def initialize(regex)
        @regex = regex
        @matches = []
      end
    
      def filter(node_set)
        @matches += node_set.find_all { |x| x['id'] =~ @regex }
      end
    end.new(full_regex)
    
    value.css("div.foo:filter()", filter_by_id)
    filter_by_id.matches.each do |node|
      puts node
    end
    

    【讨论】:

      【解决方案2】:

      基于上述答案的更简单的方法:

      regex = /subject|header/
      headers = doc.css("table td:nth-child(1) div").find_all do
        |h| h['class'] =~ regex
      end
      

      感谢您发布这个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-07
        • 2013-03-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多