我有一個2.4 MB的XML文件,從Microsoft Project導出(嘿,我是受害者在這裏!),從中請求我提取某些重新呈現的細節。忽略請求的智能或其他方面,我應該從Ruby的角度首先嚐試使用哪個庫?對於2.4MB XML文件,您會推薦哪種Ruby XML庫?
我知道以下(排名不分先後):
我喜歡的東西打包成一個紅寶石,我懷疑奇爾卡特圖書館沒有。
表現並不是一個大問題 - 我不希望事情需要每天運行一次(每週更多一次)。我更感興趣的是與XML相關的任何東西都很容易使用。
編輯:我試過gemified的:
角度來說,Hpricot是,由國家英里,最簡單的。例如,提取SaveVersion標籤在這個XML內容(保存在一個名爲,說「的test.xml」)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Project xmlns="http://schemas.microsoft.com/project">
<SaveVersion>12</SaveVersion>
</Project>
需要這樣的:
doc = Hpricot.XML(open('test.xml'))
version = (doc/:Project/:SaveVersion).first.inner_html
角度來說,Hpricot似乎對命名空間相對漠不關心,在這個例子中是很好的:只有一個,但可能是一個複雜文檔的問題。由於hpricot也非常慢,我寧願想象這會是一個解決問題的問題。
libxml-ruby快了一個數量級,理解命名空間(我花了好幾個小時才弄清楚),並且更接近XML金屬 - XPath查詢和其他所有內容都在那裏。如果像我一樣,只有在極端的脅迫條件下才開放XML文檔,這不一定是件好事。幫助程序模塊在提供如何有效處理默認名稱空間的示例方面很有幫助。這大致就是我結束了(我不以任何方式維護其美,正確性或其他價值,它只是我在哪裏現在):
xml_parser = XML::Parser.new
xml_parser.string = File.read(path)
doc = xml_parser.parse
@root = doc.root
@scopes = { :in_node => '', :in_root => '/', :in_doc => '//' }
@ns_prefix = 'p'
@ns = "#{@ns_prefix}:#{@root.namespace[0].href}"
version = @root.find_first(xpath_qry("Project/SaveVersion", :in_root), @ns).content.to_i
def xpath_qry(tags, scope = :in_node)
"#{@scopes[scope]}" + tags.split(/\//).collect{ |tag| "#{@ns_prefix}:#{tag}"}.join('/')
end
我還在辯論的利弊:libxml代表其額外的嚴謹性,hpricot代表純粹的_why代碼風格。
編輯再次,稍晚:我發現HappyMapper('寶石安裝happymapper'),這是巨大的前景,如果還處於早期階段。這是聲明式的,大部分是可行的,儘管我發現了一些邊緣案例,我還沒有修復。它可以讓你做這樣的東西,它解析我的谷歌閱讀器OPML:
module OPML
class Outline
include HappyMapper
tag 'outline'
attribute :title, String
attribute :text, String
attribute :type, String
attribute :xmlUrl, String
attribute :htmlUrl, String
has_many :outlines, Outline
end
end
xml_string = File.read("google-reader-subscriptions.xml")
sections = OPML::Outline.parse(xml_string)
我已經愛它,即使它不完美。
Oh noes!一個2.4 MB的XML文件!驚恐的事件! – Will 2008-09-24 10:13:54
嗯,我認爲答案可能會有所不同,如果它是2.4 GB ...;) – 2008-09-24 10:15:12