2013-10-11 36 views
2

我有一個很大的XML文檔,我正在分析它。在這個文檔中,許多標籤都有不同的屬性。例如:在將XML轉換爲Ruby散列時保留屬性

<album> 
<song-name type="published">Do Re Mi</song-name> 
</album> 

目前,我使用鐵路的哈希解析庫,要求'active_support/core_ext/hash'

當我將它轉換爲散列值時,它將刪除屬性。它返回:

{"album"=>{"song-name"=>"Do Re Mi"}} 

如何維護這些屬性,在這種情況下,type="published"屬性?

這似乎是以前在「How can I use XML attributes when converting into a hash with from_xml?」中提出的,它沒有確定的答案,但是那是從2010年開始的,而且我很好奇自從那時起情況發生了變化。或者,我想知道是否知道解析此XML的另一種方法,以便我仍然可以包含屬性信息。

回答

4

將XML轉換爲散列不是一個好的解決方案。您留下的哈希值比原始XML更難解析。此外,如果XML太大,則會留下散列,這些散列不適合內存,無法處理,而原始XML可以使用SAX解析器進行解析。

假設該文件是不會加載時壓倒你的記憶,我推薦使用Nokogiri解析它,做這樣的事情:

require 'nokogiri' 

class Album 

    attr_reader :song_name, :song_type 
    def initialize(song_name, song_type) 
    @song_name = song_name 
    @song_type = song_type 
    end 
end 

xml = <<EOT 
<xml> 
    <album> 
    <song-name type="published">Do Re Mi</song-name> 
    </album> 
    <album> 
    <song-name type="unpublished">Blah blah blah</song-name> 
    </album> 
</xml> 
EOT 

albums = [] 
doc = Nokogiri::XML(xml) 
doc.search('album').each do |album| 
    song_name = album.at('song-name') 
    albums << Album.new(
     song_name.text, 
     song_name['type'] 
    ) 
end 

puts albums.first.song_name 
puts albums.last.song_type 

,輸出:

Do Re Mi 
unpublished 

的代碼首先定義一個合適的對象來保存你想要的數據。將XML解析爲DOM時,代碼將遍歷所有<album>節點,並提取信息,定義類的實例,並將其附加到albums陣列。

運行後,您將擁有一個數組,您可以走路,處理每個項目,將其存儲到數據庫中,或者根據需要操作它。但是,如果您的目標是將該信息插入到數據庫中,那麼讓DBM讀取XML並直接導入它會更聰明。

+0

弗裏金輝煌,錫文。我很高興你早早阻止了我。這非常有幫助。 – CodeBiker

+0

我沒有聲稱這是輝煌的,它只是我該怎麼做。如果您遇到任何其他問題,請告知我們。解析XML/HTML有時會非常令人沮喪。 –

-1

正如在上面鏈接的問題中,Nokogiri是(簡短)答案。

如果你可以提供一些示例代碼,有人可能會想出更好的答案。

2

這是主動支持的問題XMLConverter類 請將以下代碼添加到您的任何初始化文件。

module ActiveSupport 
    class XMLConverter 
     private 
      def become_content?(value) 
       value['type'] == 'file' || (value['__content__'] && (value.keys.size == 1 && value['__content__'].present?)) 
      end 
    end 
end 

它會給你如下輸出。

例輸入XML

xml = '<album> 
    <song-name type="published">Do Re Mi</song-name> 
</album>' 

Hash.from_xml(xml) 

輸出將被

{"album"=>{"song_name"=>{"type"=>"published", "__content__"=>"Do Re Mi"}}} 
0

其實,我認爲它的垃圾方法,它檢查type屬性,如果它不返回哈希它會返回真的在方法中變成了什麼?返回false。哪一個是process_hash方法中的最後一個檢查。所以它將返回nil作爲type屬性,並不會爲它構建散列。

對於那些有興趣是什麼,我說的是在積極支持創業板active_support/core_ext /散列/ conversions.rb

module ActiveSupport class XMLConverter private def garbage?(value) false end end end

我只是將其默認爲false,它爲我工作,但它可能不適合每個人。

相關問題