gpt4 book ai didi

ruby - 使用 libxml-ruby 逐 block 处理大型 XML 文件

转载 作者:数据小太阳 更新时间:2023-10-29 07:29:35 24 4
gpt4 key购买 nike

我想读一本大书XML包含超过一百万个小型书目记录(如 <article>...</article> )的文件,使用 Ruby 中的 libxml。我已经尝试将 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

最佳答案

当处理大的 XML 文件时,您应该使用流解析器来避免将所有内容都加载到内存中。有两种常见的方法:

  • 推送解析器,例如 SAX,您可以在其中对遇到的标签使用react(请参阅 tadman 回答)。
  • 拉动解析器,您可以在其中控制 XML 文件中的“光标”,您可以使用简单的原语(例如上移/下移等)移动该光标。

我认为如果你只想检索一些字段,推送解析器很好用,但它们通常用于复杂的数据提取很困惑,并且通常使用 case... when... 构造

在我看来,拉式解析器是基于树的模型和推式解析器之间的一个很好的替代方案。你可以找到一个 nice article在 Dobb 博士关于使用 REXML 拉解析器的日志中。

关于ruby - 使用 libxml-ruby 逐 block 处理大型 XML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2000118/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com