这篇文章主要介绍了Ruby中XML格式数据处理库REXML的使用方法指南,值得注意的REXML库处理XML字符串时的编码问题,是需要的朋友可以参考下

以树方式使用 REXML
REXML 的目的是 正好够用。在最大程度上,它能很好地完成任务。 实际上, REXML 支持两种不同样式的 XML 处理 ― “树”和“流”。 第一种样式是 DOM 所尝试要做的更简单的版本;第二种样式是 SAX 所尝试要做的更简单的版本。 让我们先研究树样式。假设我们要提取上一个示例中的同一个地址簿文档。 下面的示例来自我所创建的经修改的 eval.rb ; 标准 eval.rb (链接到 Ruby 教程)可以根据对复杂对象的表达式求值显示非常长的计算结果 ― 我的 eval.rb 在没有错误发生的情况下不作出反应:
如何使用 REXML 来引用嵌套数据

ruby> require "rexml/document"
ruby> include REXML
ruby> addrbook = (Document.new File.new "address.xml").root
ruby> persons = addrbook.elements.to_a("//person")
ruby> puts persons[1].elements["address"].attributes["city"]
New York

这个表达式很普通。 .to_a() 方法创建文档中所有 <person> 元素的数组,在其它命名中它可能是有用的。 元素有点象 DOM 节点,但它其实更接近于 XML 本身(而且使用起来也更简单)。 .to_a() 的参数是 XPath,在这种情况下,可以标识文档中任何地方的所有 <person> 元素。如果我们只需要第一层上的元素,可以使用:
创建匹配元素的数组

ruby> persons = addrbook.elements.to_a("/addressbook/person")

我们甚至可以更直接地将 XPath 用作 .elements 属性的重载索引。例如:
使用 REXML 来引用嵌套数据的另一种方法

ruby> puts addrbook.elements["//person[2]/address"].attributes["city"]
New York

请注意,XPath 使用基于 1 的索引,不象 Ruby 和 Python 数组使用基于 0 的索引。换句话说, 它仍是我们正在检查其所在城市的同一个人。通过查看 REXML 请注意,XPath 使用基于 1 的索引,不象 Ruby 和 Python 数组使用基于 0 的索引。换句话说, 它仍是我们正在检查其所在城市的同一个人。通过查看
用 REXML 显示元素的 XML 源代码

ruby> puts addrbook.elements["//person[2]/address"]
<address city='New York' street='118 St.' number='344' state='NY'/>
ruby> puts addrbook.elements["//person[2]/contact-info"]
<contact-info>
 <email address='[email protected]'/>
 <home-phone number='03-3987873'/>
</contact-info>

此外,XPath 不必只与一个元素匹配。我们已在定义 persons 数组时看见过,但另一个示例强调了这一点:
将多个元素与 XPath 匹配

ruby> puts addrbook.elements.to_a("//person/address[@state='CA']")
<address city='Sacramento' street='Spruce Rd.' number='99' state='CA'/>
<address city='Los Angeles' street='Pine Rd.' number='1234' state='CA'/>

与此相反, .elements 属性的索引只产生 第一个匹配的元素:
当 XPath 只匹配第一次出现时

ruby> puts addrbook.elements.to_a("//person/address[@state='CA']")
<address city='Sacramento' street='Spruce Rd.' number='99' state='CA'/>
<address city='Los Angeles' street='Pine Rd.' number='1234' state='CA'/>

也可以通过 REXML 中的 XPath 类使用 XPath 地址, 它具有诸如 .first() 、 .each() 和 .match() 这样的方法。
REXML 元素的一个独特的惯用方法是 .each 迭代器。虽然 Ruby 有一个可对集合进行操作的循环结构 for , 但 Ruby 程序员通常更喜欢使用迭代器方法来将控制传递给代码块。下面的两种结构是等价的, 但第二种结构有更为自然的 Ruby 感觉:
通过在 REXML 中匹配 XPath 进行迭代

ruby> for addr in addrbook.elements.to_a("//address[@state='CA']")
  |  puts addr.attributes["city"]
  | end
Sacramento
Los Angeles
ruby> addrbook.elements.each("//address[@state='CA']") {
  |  |addr| puts addr.attributes["city"]
  | }
Sacramento
Los Angeles

以流方式使用 REXML
出于“正好够用”的目的, REXML 的树方式可能是 Ruby 语言最简单的方法。 但 REXML 还提供了一种流方式,它象是 SAX 的更轻量级的变体。 正如使用 SAX 一样, REXML 没有向应用程序程序员提供来自 XML 文档的缺省数据结构。 相反,“listener”或“handler”类负责提供响应文档流中各种事件的一组方法。 以下是常用集合:开始标记、结束标记、遇到的元素文本等等。
虽然流方式远远没有象以树方式工作那样容易,但通常它的速度要快很多。 REXML 教程声称流方式的速度要快 1500倍。 虽然我没有尝试过对它进行基准测试,但我猜想这是一种有限的情况(我的小示例在树方式中也是瞬间完成的)。 总之,如果速度要紧,那么速度上的差异很可能是显著的。
让我们研究一个非常简单的示例,它所做的事情与上面的“列出加州城市”示例相同。 对它进行扩展以用于复杂的文档处理相对比较简单:
REXML 中 XML 文档的流处理

ruby> require "rexml/document"
ruby> require "rexml/streamlistener"
ruby> include REXML
ruby> class Handler
  |  include StreamListener
  |  def tag_start name, attrs
  |    if name=="address" and attrs.assoc("state")[1]=="CA"
  |     puts attrs.assoc("city")[1]
  |    end
  |  end
  | end
ruby> Document.parse_stream((File.new "address.xml"), Handler.new)
Sacramento
Los Angeles

流处理示例中要注意的一件事情是,标记属性被作为一组数组传递, 它要处理的工作比起散列要稍微多一点(但可能在库中创建会更快)。

编码问题
REXML所有文本节点中都是以UTF-8编码的,所有调用的代码都要注意这一点,在程序中,传递给REXML的字符串必须是经过UTF-8编码的。

REXML不可能总是正确猜测出你的文本的编码方式,所以它总是假定为UTF-8编码。同时,如果你试图添加其他编码方式的文本,REXML不会发 出警告。添加者必须保证自己添加的是UTF-8的文本。如果添加标准的ASCII 7位编码,是没有关系的。如果使用ISO8859-1文本,必须在添加之前转换为UTF-8编码。可以使用text。unpack("C")。pack("U")。变更编码进行输出,只有Document。write()和Document。to_s() 支持。如果需要输出特定编码的节点,必须用Output把输出对象包装起来。

e = Element.new "<a/>"
e.text = "fxfcr"  # ISO-8859-1 '??'
o = ''
e.write( Output.new( o, "ISO-8859-1" ) )

pk10开奖结果可以向Output传递任何支持的编码。

最新资讯
5G手机三季度排队亮相 但年内渗透率不足整体市场1%

5G手机三季度排队亮相

5G手机的“百米冲刺”到了最后阶段,第一波5G手机出货潮
AI作曲颠覆音乐产业 95%从业者可能被取代

AI作曲颠覆音乐产业 9

过去几年,许多科技公司、研究机构和个人都在探索利用AI
外管局关注跨境支付“无证驾驶”

外管局关注跨境支付“

跨境支付市场近期不平静,对于“无证驾驶”机构而言,可谓
苹果突然在印度停售多款手机

苹果突然在印度停售多

印度停售iPhone SE、iPhone 6、iPhone 6Plus 和 iPhon
5G时代须警惕短视频侵权大爆发

pk10开奖结果5G时代须警惕短视频侵

随着5G时代的到来,短视频或将迎来新一轮爆发。
蔚来拟拆分NIO Power独立融资

蔚来拟拆分NIO Power

蔚来将拆分旗下能源补给服务NIO Power,寻求在今年四季
最新文章
Ruby编写HTML脚本替换小程序的实例分享

Ruby编写HTML脚本替换

这篇文章主要介绍了Ruby编写HTML脚本替换小程序的实例
解析proxy代理模式在Ruby设计模式开发中的运用

解析proxy代理模式在R

这篇文章主要介绍了proxy代理模式在Ruby设计模式开发
Ruby on Rails中Rack中间件的基础学习教程

Ruby on Rails中Rack

Rack是一个连接Ruby程序与服务器程序之间的中间件,甚
以MVC的思维方式来理解Ruby on Rails框架的设计结构

以MVC的思维方式来理

RubyonRails是Ruby世界中Web开发框架的代名词,人气相
Ruby基本的环境变量设置以及常用解释器命令介绍

Ruby基本的环境变量设

这篇文章主要介绍了Ruby基本的环境变量设置以及常用解
Ruby的基础语法入门学习教程

Ruby的基础语法入门学

这篇文章主要介绍了Ruby的基础语法入门学习教程,包括
pk10开奖结果_ZtJjst pk10开奖结果_2ONihk pk10开奖结果pk10开奖结果_bxZEfDQ pk10开奖结果pk10开奖结果_S8PI9i pk10开奖结果_tzQiSnz pk10开奖结果_nHZ43X pk10开奖结果_BN7yuAn pk10开奖结果_ldLWX pk10开奖结果_n17O9i pk10开奖结果_rE7GaW