Ruby怎么解析XML REXML库使用教程

REXML 是 Ruby 标准库内置的轻量 XML 解析方案,支持字符串/文件解析、XPath 查询、树遍历、动态生成与格式化输出,适用于中小型任务,需注意命名空间、空白处理、大文件及编码问题。

Ruby 解析 XML 最常用、标准库自带的方案就是 REXML。它轻量、无需额外安装,适合中小型 XML 处理任务(如读取配置、解析 API 响应、生成简单 XML 报文等)。下面用清晰、实用的方式讲清楚怎么用。

加载和基础解析:从字符串或文件开始

REXML 默认已包含在 Ruby 标准库中,直接 require 即可。解析入口通常是 REXML::Document

  • 从字符串解析:
    require 'rexml/document'
    doc = REXML::Document.new("Hello")
  • 从文件解析:
    doc = REXML::Document.new(File.read("data.xml"))(注意编码,如有中文建议加 File.read("data.xml", encoding: "UTF-8")

提取元素内容:用 XPath 或遍历方式

获取节点最直观的是 XPath —— 简洁且表达力强:

  • 找所有 的文本:
    doc.elements.each("//item") { |e| puts e.text }
  • 按属性筛选(比如 id=1):
    doc.elements.each("//item[@id='1']") { |e| puts e.text }
  • 获取某个节点的属性值:
    e.attributes["id"]e 是一个 REXML::Element

也可用树形遍历(适合逻辑较复杂、需逐层判断的场景):

doc.root.each_element do |child|
puts "#{child.name}: #{child.text}"
end

修改和生成 XML:构建新文档或更新现有结构

REXML 支持动态创建和修改:

  • 新建文档并添加元素:
    doc = REXML::Document.new
    root = doc.add_element("response")
    root.add_element("status").text = "success"
    root.add_element("count").text = "42"
  • 向已有元素追加子节点:
    item = doc.root.add_element("item")
    item.add_attribute("type", "urgent")
    item.text = "Fix bug now"
  • 输出格式化 XML(带缩进):
    require 'rexml/formatters'
    formatter = REXML::Formatters::Pretty.new(2)
    formatter.write(doc, $stdout)

常见坑与注意事项

实际用时容易踩几个小坑:

  • 默认不处理命名空间(namespace),若 XML 含 xmlns,需显式声明并使用前缀,例如:
    doc = REXML::Document.new(xml)
    doc.namespaces["ns"] = "http://example.com/ns"
    doc.elements["//ns:item"]
  • 文本节点可能含空白换行(尤其格式化 XML),用 e.text.strip 更安全
  • 大文件慎用 DOM 方式(全部载入内存),可改用 REXML::Parsers::BaseParser 或考虑 Nokogiri(更高效,但需 gem install)
  • 中文乱码?确保源 XML 声明编码一致(如 ),Ruby 读取时也指定 encoding