【问题标题】:How to search an XML when parsing it using SAX in nokogiri在 nokogiri 中使用 SAX 解析 XML 时如何搜索 XML
【发布时间】:2010-12-27 01:45:06
【问题描述】:

我有一个简单但巨大的 xml 文件,如下所示。我想使用 SAX 解析它,并且只打印出 title 标签之间的文本。

<root>
    <site>some site</site>
    <title>good title</title>
</root>

我有以下代码:

require 'rubygems'
require 'nokogiri'
include Nokogiri

class PostCallbacks < XML::SAX::Document
  def start_element(element, attributes)
    if element == 'title'
      puts "found title"
    end
  end

  def characters(text)
    puts text
  end
end

parser = XML::SAX::Parser.new(PostCallbacks.new)
parser.parse_file("myfile.xml")

问题是它在所有标签之间打印文本。如何在title 标签之间打印文本?

【问题讨论】:

  • “巨大”有多大?我曾经使用 SAX 进行解析,因为我的机器上的文件比可用 RAM 大,但现在我有大量可用的 RAM,所以我通常使用 DOM 来解析。
  • 感谢您提出这个问题

标签: ruby nokogiri sax


【解决方案1】:

您只需要跟踪您何时在&lt;title&gt; 内,以便characters 知道何时应该注意。可能是这样的(未经测试的代码):

class PostCallbacks < XML::SAX::Document
  def initialize
    @in_title = false
  end

  def start_element(element, attributes)
    if element == 'title'
      puts "found title"
      @in_title = true
    end
  end

  def end_element(element)
    # Doesn't really matter what element we're closing unless there is nesting,
    # then you'd want "@in_title = false if element == 'title'"
    @in_title = false
  end

  def characters(text)
    puts text if @in_title
  end
end

【讨论】:

    【解决方案2】:

    上面接受的答案是正确的,但是它有一个缺点,即使它在开头找到&lt;title&gt;,它也会遍历整个 XML 文件。

    我确实有类似的需求,最后我写了一个saxy ruby​​ gem,旨在在这种情况下高效。它在底层实现了 Nokogiri 的 SAX Api。

    以下是您的使用方法:

    require 'saxy'
    title = Saxy.parse(path_to_your_file, 'title').first
    

    当它发现第一次出现&lt;title&gt;标签时会立即停止。

    【讨论】:

      猜你喜欢
      • 2011-06-17
      • 2010-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多