我试图用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的。
感谢。
答案 0 :(得分:0)
运行此内容后,您的记忆会发生什么:
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'))