使用 Nokogiri 的 SAX 解析器从 Redis 解析大型 XML



我正在尝试用Nokogiri的SAX解析器解析一个大型XML文件。

当我从一个文件中读取相同的数据时,它工作得很好,但是当从Redis读取数据时,内存会超过1GB。

下面是我可以用来复制这个问题的最基本的代码。

知道为什么会这样吗?

class WordsList < Nokogiri::XML::SAX::Document
  def start_element name, attrs = []
  end
end

我是这样加载的:

  doc              = WordsList.new
  parser           = Nokogiri::XML::SAX::Parser.new doc
  parser.parse row_data

row_data方法是从Redis获取XML。

谢谢。

当你运行这个时,你的内存会发生什么?

require 'nokogiri'
File.open('xml.xml', 'w') do |f|
  f.puts '<?xml version="1.0" encoding="UTF-8"?>'
  f.puts '<my_root>'
  xml = <<'END_OF_XML'
  <note>
  <to>Tove</to>
  <from gender="F" age="25" address="123 Maple St.">Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
  </note>
  <note>
  <to>Tove</to>
  <from gender="F" age="25" address="123 Apple St.">Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
  </note>
END_OF_XML
  f.puts xml * 500_000 
  f.puts '</my_root>'
end
class WordsList < Nokogiri::XML::SAX::Document
  attr_writer :sort_key
  attr_reader :obj
  def initialize
    @obj      = []
    @sort_key = :address
    @limit    = 10
  end
  def sort_key
    @sort_key.to_s
  end
  def start_element name, attrs = []
    add_to_list Hash[attrs] if name == 'from'
  end
  def add_to_list hash
    @obj.push hash
    @obj = sorted.first(@limit)
  end
  def sorted
    @obj.sort_by do |item|
      begin
        Float(item[sort_key].gsub(",", ""))
      rescue ArgumentError
        item[sort_key].downcase
      end
    end.reverse
  end
end
my_handler = WordsList.new
parser = Nokogiri::XML::SAX::Parser.new(my_handler)
parser.parse(File.open('xml.xml'))

相关内容

  • 没有找到相关文章

最新更新