Ruby程序创建和解析XML文件的方法详解
时间:2026-08-17 | 作者:实验室老王 | 阅读:0在Ruby的世界里,处理XML文件是家常便饭。无论是生成配置文件,还是解析接口返回的数据,你总得和它打交道。
今天这篇,我们就来聊聊两个最趁手的工具:Builder和REXML。一个负责造,一个负责拆,配合好了,事半功倍。
使用Builder创建XML
先说怎么造一个XML出来。Builder这个库用起来非常清爽,几行代码就能生成结构清晰的文档。
安装它只需要一条命令:
gem install builder
下面来看一个具体例子。我们想生成一个包含书本信息的XML,代码如下:
require 'builder'
x = Builder::XmlMarkup.new(:target => $stdout, :indent => 1)
#":target =>$stdout"参数:指示输出内容将被写向标准输出控制台
#":indent =>1"参数:XML输出形式将被缩进一个空格字符
x.instruct! :xml, :version =>'1.1', :encoding => 'gb2312'
x.comment! "书本信息"
x.library("shelf" => "Recent Acquisitions") {
x.section("name" => "ruby"){
x.book("isbn" => "0672310001"){
x.title "Programming Ruby"
x.author "Yukihiro "
x.description "Programming Ruby - The Pragmatic Programmer's Guide"
}
}
}
这里有两个参数值得注意:
:target => $stdout:把结果直接打印到控制台上。:indent => 1:让输出带有1个空格的缩进,方便阅读。
最后p x会把生成的XML对象也打印出来。执行后的输出结果如下:
Programming Ruby Yukihiro Programming Ruby - The Pragmatic Programmer's Guide
生成结果干净利落,该有的都有。
使用REXML解析XML
造完了XML,接下来就得学会怎么读它。REXML是Ruby自带的XML解析库,纯Ruby实现,用起来相当顺手。
它提供了两种主流的解析方式:
- DOM-like(树解析):整个文档读进内存,变成一棵树。
- SAX-like(流解析):边读边处理,适合大文件。
下面我们从一个具体的books.xml文件出发,看看怎么玩。
先准备一份示例数据:
The Ruby Way Hal Fulton Second edition. The book you are now reading. Ain't recursion grand The Case for Mars Robert Zubrin Pushing toward a second home for the human race. First Man: The Life of Neil A. Armstrong James R. Hansen Definitive biography of the first man on the moon.
1. Tree Parsing(DOM-like)
树解析是最直观的方式。先把文件读进来,然后像操作一棵树一样获取节点。
需要先require相应的库:
require 'rexml/document'
include REXML
input = File.new("books.xml")
doc = Document.new(input)
root = doc.root
puts root.attributes["shelf"] # Recent Acquisitions
doc.elements.each("library/section") { |e| puts e.attributes["name"] }
# Output:
# Ruby
# Space
doc.elements.each("*/section/book") { |e| puts e.attributes["isbn"] }
# Output:
# 0672328844
# 0321445619
# 0684835509
# 074325631X
sec2 = root.elements[2]
author = sec2.elements[1].elements["author"].text # Robert Zubrin
有几个小细节需要留意:
- XML中的属性被存储为一个哈希,所以用
attributes["key"]就能取值。 - 通过整数索引访问子元素时,REXML是从1开始计数的,不是0。
这一点在写遍历逻辑时要特别小心。
2. Stream Parsing(SAX-like)
当你面对的XML文件有几十上百兆时,树解析就不太合适了。因为内存会吃不住。
这时候就该流解析上场了。REXML提供了StreamListener模块,你只需要定义一个监听器类,然后在解析过程中回调相应的方法。
看个例子:
require 'rexml/document'
require 'rexml/streamlistener'
include REXML
class MyListener
include REXML::StreamListener
def tag_start(*args)
puts "tag_start: #{args.map {|x| x.inspect}.join(', ')}"
end
def text(data)
return if data =~ /^w*$/ # whitespace only
abbrev = data[0..40] + (data.length > 40 "..." : "")
puts " text : #{abbrev.inspect}"
end
end
list = MyListener.new
source = File.new "books.xml"
Document.parse_stream(source, list)
这段代码会依次输出每个标签的开始信息和文本内容。注意StreamListener提供的回调方法默认都是空的。
你只需要覆盖自己需要的那几个。输出效果大概如下:
tag_start: "library", {"shelf"=>"Recent Acquisitions"}
tag_start: "section", {"name"=>"Ruby"}
tag_start: "book", {"isbn"=>"0672328844"}
tag_start: "title", {}
text : "The Ruby Way"
这种方式的好处是内存占用几乎恒定,非常适合处理大型文档。
3. XPath
REXML还内置了对XPath的支持。你可以用非常简洁的路径表达式来定位节点。
比如:
book1 = XPath.first(doc, "//book") # Info for first book found
p book1
# Print out all titles
XPath.each(doc, "//title") { |e| puts e.text }
# Get an array of all of the "author" elements in the document.
names = XPath.match(doc, "//author").map {|x| x.text }
p names
运行结果:
... > The Ruby Way The Case for Mars First Man: The Life of Neil A. Armstrong ["Hal Fulton", "Robert Zubrin", "James R. Hansen"]
XPath的强大之处在于它支持通配符、条件筛选等高级语法。
不过日常开发里,用//和./基本就够用了。如果你经常写XML处理脚本,花五分钟熟悉一下XPath,回报率极高。
总结
总的来说,Builder和REXML的组合,覆盖了Ruby日常XML处理的绝大部分场景。
- Builder负责创建XML。
- REXML负责解析和查询XML。
创建、解析、查询,一套下来行云流水。
如果非要说有什么不足,那就是REXML的解析速度在超大文件面前不如Nokogiri。
但大多数情况下,它轻量、稳定、无需额外安装,已经足够了。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- 使用RVM切换Ruby与Rails版本的实现方法
- 时间:2026-08-18
-
- Ruby语言是什么及入门使用方法
- 时间:2026-08-18
-
- Ruby on Rails网站项目搭建入门指南
- 时间:2026-08-18
-
- Ruby插入排序算法实现与二路插入排序代码示例
- 时间:2026-08-18
-
- Ruby图片滤镜算法实现代码与核心原理
- 时间:2026-08-18
-
- Ruby中Hash哈希结构基本操作方法详解
- 时间:2026-08-18
-
- Ruby面向对象编程:类方法与类扩展详解
- 时间:2026-08-18
-
- Ruby正则表达式语法详解与常用示例代码
- 时间:2026-08-18
精选合集
更多大家都在玩
大家都在看
更多-
- 糖尿病完全不能吃糖吗
- 时间:2026-09-15
-
- 蚂蚁庄园小课堂2026年9月16日最新题目答案
- 时间:2026-09-15
-
- 小鸡答题今天的答案是什么2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园每日答题答案2026年9月16日
- 时间:2026-09-15
-
- 以下哪种粮食是酿造绍兴黄酒的主要原料 蚂蚁庄园今日答案9月16日
- 时间:2026-09-15
-
- 劝学名句“及时当勉励,岁月不待人”出自哪位诗人 蚂蚁庄园今日答案9.16
- 时间:2026-09-15
-
- 蚂蚁庄园今天答题答案2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园答题今日答案2026年9月16日
- 时间:2026-09-15
