HOWTO · Ruby
用 Ruby 解析 XML
本文展示了如何在 Ruby 中使用 gem nokogiri 解析 XML 文件。
本页内容
Nokogiri 可让 Ruby 程序将 XML 解析为可查询和修改的文档。本指南介绍安装、解析、选择元素、读取文本和属性,以及写入修改结果。完整示例会在 Nokogiri 已安装时使用它;如果没有安装,则使用 Ruby 标准库中的 REXML 作为后备方案,因此无需外部 gem 也能完成相同的操作流程。
安装 Nokogiri
在终端运行 gem install nokogiri,即可为应用所使用的 Ruby 环境安装 Nokogiri。如果项目会追踪依赖项,请将 gem 'nokogiri' 加入 Gemfile,并安装声明的依赖项,以便项目能够使用该 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
示例会将 catalog 字符串解析为 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') 选择作为 book 直接子元素的标题。
读取 XML 属性
元素的属性与其文本内容彼此独立。Nokogiri 的方括号访问方式不需要在属性名前加 @:book['id'] 会从选中的 book 节点读取 id 值。在完整示例中,book 是 doc.at_xpath('//book') 返回的第一本书;标题修改前会先打印它的 id。若没有匹配的 book,查找会返回 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 适合表达关系和条件,例如通过父级 book 选择标题,或按属性定位节点。CSS 选择器则以简洁、熟悉的语法匹配常见元素和属性。对于这里的 catalog 结构,doc.xpath('//book/title') 和 doc.css('book > title') 都会选择作为 book 直接子元素的标题。请选择更清楚表达目标关系的写法;两种方式返回的节点都可以检查或修改。选择依据是如何表达查询,而不是对速度作普遍排名。