簡體   English   中英

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

[英]Processing large XML file with libxml-ruby chunk by chunk

我想在Ruby中使用libxml讀取包含超過一百萬個小書目記錄(如<article>...</article> )的大型XML文件。 我已經嘗試將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文件中的“光標”,您可以使用簡單的原語(如上/下移等)移動它。

我認為推送解析器很好用,如果你只想檢索一些字段,但它們通常很麻煩,用於復雜的數據提取,並且經常用用case... when...構造時

在我看來,pull解析器是基於樹的模型和推送解析器之間的一個很好的選擇。 您可以在Dr. Dobb的期刊中找到一篇關於使用REXML進行拉解析的好文章

處理XML時,兩個常見選項是基於樹的,基於事件的。 基於樹的方法通常讀取整個XML文檔,並且可能消耗大量內存。 基於事件的方法不使用額外的內存,但除非您編寫自己的處理程序邏輯,否則不會執行任何操作。

基於事件的模型由SAX樣式的解析器和衍生實現使用。

REXML示例: http//www.iro.umontreal.ca/~lapalme/ForestInsteadOfTheTrees/HTML/ch08s01.html

REXML: http//ruby-doc.org/stdlib/libdoc/rexml/rdoc/index.html

我有同樣的問題,但我想我通過調用Node#remove來解決它! 在展開的節點上。 在你的情況下,我認為你應該做的事情

my_node = dblp.expand
[do what you have to do with my_node]
dblp.next
my_node.remove!

不確定為什么會這樣,但是如果你看一下LibXML :: XML :: Reader#expand的源代碼,就會有關於釋放節點的評論。 我猜測Reader#expand將節點關聯到Reader,你必須調用Node #remove! 釋放它。

即使有這種黑客攻擊,內存使用也不是很好,但至少它沒有繼續增長。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM