加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

使用libkml-ruby chunk处理大型XML文件

发布时间:2020-12-17 02:58:15 所属栏目:百科 来源:网络整理
导读:我想在 Ruby中使用libxml读取包含超过一百万个小书目记录的大型 XML文件(例如 article … / article).我已经尝试将Reader类与expand方法结合使用来按记录读取记录,但我不确定这是正确的方法,因为我的代码占用了内存.因此,我正在寻找一个如何方便地处理记录的
我想在 Ruby中使用libxml读取包含超过一百万个小书目记录的大型 XML文件(例如< article> …< / article>).我已经尝试将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这样的解析器,当你得到它们时,你会对遇到的标签作出反应(参见tadman的回答).
>拉动解析器,您可以在其中控制XML文件中的“光标”,您可以使用简单的原语(如上/下移等)移动它.

我认为推送解析器很好用,如果你只想检索一些字段,但它们通常很麻烦,用于复杂的数据提取,并且经常用用例…当……构造时

在我看来,pull解析器是基于树的模型和推送解析器之间的一个很好的选择.您可以在Dr. Dobb的期刊中找到关于使用REXML的拉解析器的nice article.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读