我有一个非常大的XML文件(300mb),格式如下:
<data>
<point>
<id><![CDATA[1371308]]></id>
<time><![CDATA[15:36]]></time>
</point>
<point>
<id><![CDATA[1371308]]></id>
<time><![CDATA[15:36]]></time>
</point>
<point>
<id><![CDATA[1371308]]></id>
<time><![CDATA[15:36]]></time>
</point>
</data>
Run Code Online (Sandbox Code Playgroud)
现在我需要读取它并遍历point节点为每个节点做一些事情.目前我正在和Nokogiri这样做:
require 'nokogiri'
xmlfeed = Nokogiri::XML(open("large_file.xml"))
xmlfeed.xpath("./data/point").each do |item|
save_id(item.xpath("./id").text)
end
Run Code Online (Sandbox Code Playgroud)
然而,这并不是非常有效,因为它解析了整个拥抱的一切,因此创造了巨大的内存占用(几GB).
有没有办法在块中执行此操作?如果我没弄错的话可能会被称为流式传输?
编辑
使用nokogiris sax解析器的建议答案可能没问题,但是当每个节点中有多个节点point需要从中提取内容并以不同方式处理时,它会变得非常混乱.我宁愿选择point一次访问一个,处理它,然后继续下一个"忘记"前一个,而不是返回大量的条目供以后处理.
鉴于使用Nokogiri的Reader界面这个鲜为人知(但很棒)的要点,你应该能够做到这一点:
Xml::Parser.new(Nokogiri::XML::Reader(open(file))) do
inside_element 'point' do
for_element 'id' do puts "ID: #{inner_xml}" end
for_element 'time' do puts "Time: #{inner_xml}" end
end
end
Run Code Online (Sandbox Code Playgroud)
有人应该把它变成宝石,也许是我;)
| 归档时间: |
|
| 查看次数: |
2664 次 |
| 最近记录: |