Ruby에서 libxml을 사용하는 수백만 개의 작은 서지 레코드 (예 : <article>...</article>
)가 포함 된 큰 XML 파일을 읽고 싶습니다. 레코드로 레코드를 읽는 expand
메서드와 함께 Reader 클래스를 시도했지만 코드가 메모리를 차지하기 때문에 이것이 올바른 접근 방법인지 확신 할 수 없습니다. 따라서 일정한 메모리 사용으로 레코드별로 편리하게 레코드를 처리하는 방법을 찾고 있습니다. 여기청크로 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
은 (AN <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 faults가 발생했습니다. 버그가 libxml-ruby에서 유래 한 것 같지만 지금까지 추적하지 않았습니다. 실망 스럽네. –
https://github.com/amolpujari/reading-huge-xml –