HOWTO · Ruby
用 Ruby 解析 XML
本文展示瞭如何在 Ruby 中使用 gem nokogiri 解析 XML 檔案。
本頁內容
Nokogiri 可讓 Ruby 程式將 XML 解析為文件,之後便能查詢及修改。本文將介紹安裝、解析、選取元素、讀取文字與屬性,以及寫入修改內容。完整範例會在已安裝 Nokogiri 時使用它;若未安裝,則改用 Ruby 內建的 REXML,因此不必安裝外部 Gem 也能執行相同流程。
安裝 Nokogiri
在終端機執行 gem install nokogiri,即可為應用程式使用的 Ruby 環境安裝 Nokogiri。若專案使用 Gemfile 管理相依套件,請在其中加入 gem 'nokogiri',再安裝宣告的相依套件,讓專案能使用這個 Gem。下文中的 Nokogiri 呼叫假設程式已透過 require 'nokogiri' 載入該 Gem。
解析 XML 文件
Nokogiri::XML(xml) 會解析 XML 字串,並傳回可供 Ruby 程式查詢的文件。若要解析檔案,請先讀取檔案內容,再將字串傳給解析器,例如 Nokogiri::XML(File.read(path));請使用由應用程式提供的路徑。下方範例會優先使用 Nokogiri,若無法使用該 Gem,則改用 REXML。兩種方式都會列印相同的選取值,並在記憶體中更新文件。執行此範例:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
xml = '<catalog><book id="b1"><title>Ruby Basics</title></book><book id="b2"><title>XML Guide</title></book></catalog>'
begin
require 'nokogiri'
rescue LoadError
require 'rexml/document'
end
if defined?(Nokogiri)
doc = Nokogiri::XML(xml)
doc.xpath('//book/title').each { |title| puts title.text }
book = doc.at_xpath('//book')
puts book['id']
book.at_xpath('title').content = 'Ruby XML Basics'
puts book.at_xpath('title').text
serialized_xml = doc.to_xml
else
doc = REXML::Document.new(xml)
doc.elements.each('//book/title') { |title| puts title.text }
book = doc.elements['//book']
puts book.attributes['id']
book.elements['title'].text = 'Ruby XML Basics'
puts book.elements['title'].text
serialized_xml = doc.to_s
end
Ruby Basics
XML Guide
b1
Ruby XML Basics
範例會將目錄 XML 字串解析為 Nokogiri 文件,列印兩個標題、讀取第一本書的 id、更新其標題,最後使用 to_xml 將修改後的文件序列化。序列化會傳回字串,不會變更來源檔案。若要保存修改,請將該字串寫入應用程式有權使用的目的地,例如使用 File.write(path, doc.to_xml);這會建立或覆寫目的地檔案。
選取元素並讀取文字
完整範例使用 doc.xpath('//book/title') 選取每本書底下的標題,並將每個節點的 text 各自列印在一行。若只需要一個結果,doc.at_xpath('//book/title') 會傳回第一個符合的節點;若沒有符合項目,則傳回 nil。如果來源可能缺少該元素,請先檢查結果,再呼叫節點的方法。若要處理常見的比對,也可以使用 CSS,例如以 doc.css('book > title') 選取作為書籍直接子元素的標題。
讀取 XML 屬性
元素的屬性與其文字內容是分開的。Nokogiri 的中括號存取方式使用不含 @ 的屬性名稱:book['id'] 會讀取所選書籍節點的 id 值。在完整範例中,book 是 doc.at_xpath('//book') 傳回的第一本書,並會在標題變更前列印其 id。若找不到符合的書籍,查詢會傳回 nil;若屬性不存在,中括號存取也會傳回 nil。來源可能缺少書籍或屬性時,請同時檢查這兩種情況。
修改並寫入 XML 文件
完整範例使用 book.at_xpath('title').content = 'Ruby XML Basics' 修改第一個標題,再以 doc.to_xml 將修改後的文件序列化至 serialized_xml。序列化會傳回 XML 字串,不會更動輸入檔案。若要保存修改,請使用應用程式有權寫入的目的地,將字串傳給 File.write(path, doc.to_xml);這會建立或覆寫該目的地。若要修改的節點可能不存在,請先檢查 at_xpath 的結果。
選擇 XPath 或 CSS 選取器
Nokogiri 同時支援 XPath 與 CSS 選取器。XPath 適合表達關係與條件,例如透過父層書籍選取標題,或依屬性尋找節點。CSS 選取器則以熟悉、精簡的語法處理常見的元素與屬性比對。以本文的目錄結構為例,doc.xpath('//book/title') 和 doc.css('book > title') 都會選取作為書籍直接子元素的標題。請選擇較能清楚表達查詢關係的寫法;兩者傳回的節點都可以檢視或修改。選擇依據是如何表達查詢,而非普遍適用的速度排名。