用Nokogiri的SAX解析器解析Redis的大XML

问题描述:

我想用Nokogiri的SAX解析器解析大的XML文件。用Nokogiri的SAX解析器解析Redis的大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')) 
+0

这没有问题。我缩小了范围,甚至在一个基本上空的SAX文档中,内存跳跃起来。我会更新帖子。 – 99miles

+0

'row_data方法是从Redis获取XML的。'然后如果您尚未这样做,请开始查看该方法在做什么。 – 7stud

+0

$ redis.get(key) – 99miles