我想在Ruby中使用libxml讀取包含超過一百萬個小型書目記錄(如<article>...</article>
)的大型XML文件。我已經試過Reader類與expand
方法一起按記錄讀取記錄,但我不確定這是否是正確的方法,因爲我的代碼吃掉了內存。因此,我正在尋找一個配方如何方便地記錄內存使用情況。下面是我的主循環:使用libxml-ruby塊按塊處理大型XML文件
File.open('dblp.xml') do |io|
dblp = XML::Reader.io(io, :options => XML::Reader::SUBST_ENTITIES)
pubFactory = PubFactory.new
i = 0
while dblp.read do
case dblp.name
when 'article', 'inproceedings', 'book':
pub = pubFactory.create(dblp.expand)
i += 1
puts pub
pub = nil
$stderr.puts i if i % 10000 == 0
dblp.next
when 'proceedings','incollection', 'phdthesis', 'mastersthesis':
# ignore for now
dblp.next
else
# nothing
end
end
end
這裏的關鍵是,dblp.expand
讀取整個子樹(像<article>
記錄),並把它作爲參數傳遞給工廠進行進一步的處理。這是正確的方法嗎?
在工廠方法中,我使用高級類XPath表達式來提取元素的內容,如下所示。再次,這是可行的嗎?
def first(root, node)
x = root.find(node).first
x ? x.content : nil
end
pub.pages = first(node,'pages') # node contains expanded node from dblp.expand
只是一小步:在x86上的OS X 10.6和x86上的Debian Linux上進行了更多的Ruby 1.8.7測試後,我在讀取XML文件時遇到了兩臺機器上的seg故障。我想這個錯誤源於libxml-ruby,但到目前爲止我沒有追蹤它。非常令人失望。 – 2010-01-12 20:10:27
https://github.com/amolpujari/reading-huge-xml – 2012-07-14 06:57:55