Przetwarzanie dużego pliku XML z porcją libxml-ruby przez porcję
Chciałbym przeczytać dużyXML plik zawierający ponad milion małych rekordów bibliograficznych (np<article>...</article>
) używając libxml w Ruby. Próbowałem klasy Reader w połączeniu zexpand
metoda odczytu rekordu według rekordu, ale nie jestem pewien, czy jest to właściwe podejście, ponieważ mój kod zjada pamięć. Dlatego szukam przepisu, jak wygodnie przetwarzać rekord przez zapis ze stałym wykorzystaniem pamięci. Poniżej znajduje się moja główna pętla:
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
Kluczem jest todblp.expand
czyta całe poddrzewo (jak<article>
rekord) i przekazuje go jako argument do fabryki w celu dalszego przetwarzania. Czy to właściwe podejście?
W ramach metody fabrycznej używam wysokiego poziomu wyrażenia podobnego do XPath, aby wyodrębnić zawartość elementów, jak poniżej. Ponownie, czy to jest opłacalne?
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