我想阅读一个大型的XML文件,其中包含超过一百万个小书目记录(比如<article>...</article>),它使用了Ruby。我尝试过将Reader类与expand方法结合使用,以逐条记录地读取记录,但我不确定这是不是正确的方法,因为我的代码会占用内存。因此,我正在寻找一个配方,如何方便地处理记录与恒定的内存使用率的记录。下面是我的主循环:
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发布于 2010-01-05 03:28:15
在处理大的XML文件时,您应该使用流解析器,以避免在内存中加载所有内容。有两种常见的方法:
我认为,如果您只想检索一些字段,那么使用推式解析器是很好的,但是对于复杂的数据提取来说,使用推式解析器通常很麻烦,而且通常使用case... when...构造来实现
在我看来,拉式解析器是基于树的模型和推式解析器之间的一个很好的选择。您可以在Dobb博士的日志中找到关于使用REXML的拉式解析器的nice article。
https://stackoverflow.com/questions/2000118
复制相似问题