2012-06-04 79 views
0

我對Nokogiri和Ruby頗爲陌生,希望得到一些幫助。如何在Nokogiri中使用SAX遍歷內部節點?

我正在使用class MyDoc < Nokogiri::XML::SAX::Document解析一個非常大的XML文件。現在我想遍歷塊的內部。

這是我的XML文件的格式:

<Content id="83087"> 
    <Title></Title> 
    <PublisherEntity id="1067">eBooksLib</PublisherEntity> 
    <Publisher>eBooksLib</Publisher> 
    ...... 
</Content> 

我已經可以告訴我們,如果「內容」標籤中找到,現在我想知道如何在其內部穿過。這裏是我縮短的代碼:

class MyDoc < Nokogiri::XML::SAX::Document 
    #check the start element. set flag for each element 
    def start_element name, attrs = [] 
    if(name == 'Content') 
     #get the <Title> 
     #get the <PublisherEntity> 
     #get the Publisher 
    end 
    end 


    def cdata_block(string) 
    characters(string) 
    end 

    def characters(str) 
    puts str 
    end 
end 
+0

爲什麼選擇SAX?您很有可能會在尋找Nokogiri.XML。 – pguardiario

+0

xml文件至少是1GIG,所以我希望它具有內存高效性。 – Diffy

+0

+1是的,這實際上是使用SAX的一個很好的理由 – pguardiario

回答

0

這對SAX來說很棘手。我認爲,該解決方案將需要看起來像這樣:

class MyDoc < Nokogiri::XML::SAX::Document 
    def start_element name, attrs = [] 
    @inside_content = true if name == 'Content' 
    @current_element = name 
    end 

    def end_element name 
    @inside_content = false if name == 'Content' 
    @current_element = nil 
    end 

    def characters str 
    puts "#{@current_element} - #{str}" if @inside_content && %w{Title PublisherEntity Publisher}.include?(@current_element) 
    end 
end 
1

純粹主義者可能會不同意我,但我一直在做它的方式是使用引入nokogiri遍歷巨大的文件,然後使用XmlSimple工作在文件中有一個較小的對象。這裏是我的代碼片段:

require 'nokogiri' 
require 'xmlsimple' 

def isend(node) 
    return (node.node_type == Nokogiri::XML::Reader::TYPE_END_ELEMENT) 
end 

reader = Nokogiri::XML::Reader(File.open('database.xml', 'r')) 

# traverse the file looking for tag "content" 
reader.each do |node| 
    next if node.name != 'content' || isend(node) 
    # if we get here, then we found start of node 'content', 
    # so read it into an array and work with the array: 
    content = XmlSimple.xml_in(node.outer_xml()) 
    title = content['title'][0] 
    # ...etc. 
end 

這對我來說很好。有些人可能會反對在相同的代碼中混合使用SAX和非SAX(nokogiri和XmlSimple),但出於我的目的,它可以以最小的麻煩完成工作。