在Ruby中处理XML和XSLT以及XPath的简单教程

什么是 XML ?

XML 指可扩展标记语言(eXtensible Markup Language)。

可扩展标记语言,标准通用标记语言的子集,一种用于标记电子文件使其具有结构性的标记语言。

它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。

XML解析器结构和API

XML的解析器主要有DOM和SAX两种。

  1. SAX解析器是基于事件处理的,需要从头到尾把XML文档扫描一遍,在扫描的过程中,每次遇到一个语法结构时,就会调用这个特定语法结构的事件处理程序,向应用程序发送一个事件。
  2. DOM是文档对象模型解析,构建文档的分层语法结构,在内存中建立DOM树,DOM树的节点以对象的形式来标识,文档解析文成以后,文档的整个DOM树都会放在内存中。

Ruby 中解析及创建 XML

RUBY中对XML的文档的解析可以使用这个库REXML库。

REXML库是ruby的一个XML工具包,是使用纯Ruby语言编写的,遵守XML1.0规范。

在Ruby1.8版本及其以后,RUBY标准库中将包含REXML。

REXML库的路径是: rexml/document

所有的方法和类都被封装到一个REXML模块内。

REXML解析器比其他的解析器有以下优点:

  1. 100% 由 Ruby 编写。
  2. 可适用于 SAX 和 DOM 解析器。
  3. 它是轻量级的,不到2000行代码。
  4. 很容易理解的方法和类。
  5. 基于 SAX2 API 和完整的 XPath 支持。
  6. 使用 Ruby 安装,而无需单独安装。

以下为实例的 XML 代码,保存为movies.xml:

<collection shelf="New Arrivals">
<movie title="Enemy Behind">
  <type>War, Thriller</type>
  <format>DVD</format>
  <year>2003</year>
  <rating>PG</rating>
  <stars>10</stars>
  <description>Talk about a US-Japan war</description>
</movie>
<movie title="Transformers">
  <type>Anime, Science Fiction</type>
  <format>DVD</format>
  <year>1989</year>
  <rating>R</rating>
  <stars>8</stars>
  <description>A schientific fiction</description>
</movie>
  <movie title="Trigun">
  <type>Anime, Action</type>
  <format>DVD</format>
  <episodes>4</episodes>
  <rating>PG</rating>
  <stars>10</stars>
  <description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
  <type>Comedy</type>
  <format>VHS</format>
  <rating>PG</rating>
  <stars>2</stars>
  <description>Viewable boredom</description>
</movie>
</collection>

DOM 解析器

让我们先来解析 XML 数据,首先我们先引入 rexml/document 库,通常我们可以将 REXML 在顶级的命名空间中引入:

#!/usr/bin/ruby -w

require 'rexml/document'
include REXML

xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)

# 获取 root 元素
root = xmldoc.root
puts "Root element : " + root.attributes["shelf"]

# 以下将输出电影标题
xmldoc.elements.each("collection/movie"){
  |e| puts "Movie Title : " + e.attributes["title"]
}

# 以下将输出所有电影类型
xmldoc.elements.each("collection/movie/type") {
  |e| puts "Movie Type : " + e.text
}

# 以下将输出所有电影描述
xmldoc.elements.each("collection/movie/description") {
  |e| puts "Movie Description : " + e.text
}

以上实例输出结果为:

Root element : New Arrivals
Movie Title : Enemy Behind
Movie Title : Transformers
Movie Title : Trigun
Movie Title : Ishtar
Movie Type : War, Thriller
Movie Type : Anime, Science Fiction
Movie Type : Anime, Action
Movie Type : Comedy
Movie Description : Talk about a US-Japan war
Movie Description : A schientific fiction
Movie Description : Vash the Stampede!
Movie Description : Viewable boredom
SAX-like Parsing:

SAX 解析器

处理相同的数据文件:movies.xml,不建议SAX的解析为一个小文件,以下是个简单的实例:

#!/usr/bin/ruby -w

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
xmlfile = File.new("movies.xml")
Document.parse_stream(xmlfile, list)

以上输出结果为:

tag_start: "collection", {"shelf"=>"New Arrivals"}
tag_start: "movie", {"title"=>"Enemy Behind"}
tag_start: "type", {}
 text  :  "War, Thriller"
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
 text  :  "Talk about a US-Japan war"
tag_start: "movie", {"title"=>"Transformers"}
tag_start: "type", {}
 text  :  "Anime, Science Fiction"
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
 text  :  "A schientific fiction"
tag_start: "movie", {"title"=>"Trigun"}
tag_start: "type", {}
 text  :  "Anime, Action"
tag_start: "format", {}
tag_start: "episodes", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
 text  :  "Vash the Stampede!"
tag_start: "movie", {"title"=>"Ishtar"}
tag_start: "type", {}
tag_start: "format", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
 text  :  "Viewable boredom"

XPath 和 Ruby

我们可以使用XPath来查看XML ,XPath 是一门在 XML 文档中查找信息的语言(查看:XPath 教程)。

XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言。XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。

Ruby 通过 REXML 的 XPath 类支持 XPath,它是基于树的分析(文档对象模型)。

#!/usr/bin/ruby -w

require 'rexml/document'
include REXML

xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)

# 第一个电影的信息
movie = XPath.first(xmldoc, "//movie")
p movie

# 打印所有电影类型
XPath.each(xmldoc, "//type") { |e| puts e.text }

# 获取所有电影格式的类型,返回数组
names = XPath.match(xmldoc, "//format").map {|x| x.text }
p names

以上实例输出结果为:

<movie title='Enemy Behind'> ... </>
War, Thriller
Anime, Science Fiction
Anime, Action
Comedy
["DVD", "DVD", "DVD", "VHS"]

XSLT 和 Ruby

Ruby 中有两个 XSLT 解析器,以下给出简要描述:
Ruby-Sablotron

这个解析器是由正义Masayoshi Takahash编写和维护。这主要是为Linux操作系统编写的,需要以下库:

  1. Sablot
  2. Iconv
  3. Expat

你可以在 Ruby-Sablotron 找到这些库。
XSLT4R
XSLT4R 由 Michael Neumann 编写。 XSLT4R 用于简单的命令行交互,可以被第三方应用程序用来转换XML文档。

XSLT4R需要XMLScan操作,包含了 XSLT4R 归档,它是一个100%的Ruby的模块。这些模块可以使用标准的Ruby安装方法(即Ruby install.rb)进行安装。

XSLT4R 语法格式如下:

ruby xslt.rb stylesheet.xsl document.xml [arguments]

如果您想在应用程序中使用XSLT4R,您可以引入XSLT及输入你所需要的参数。实例如下:

require "xslt"

stylesheet = File.readlines("stylesheet.xsl").to_s
xml_doc = File.readlines("document.xml").to_s
arguments = { 'image_dir' => '/....' }

sheet = XSLT::Stylesheet.new( stylesheet, arguments )

# output to StdOut
sheet.apply( xml_doc )

# output to 'str'
str = ""
sheet.output = [ str ]
sheet.apply( xml_doc )
(0)

相关推荐

  • Ruby中XML格式数据处理库REXML的使用方法指南

    以树方式使用 REXML REXML 的目的是 正好够用.在最大程度上,它能很好地完成任务. 实际上, REXML 支持两种不同样式的 XML 处理 ― "树"和"流". 第一种样式是 DOM 所尝试要做的更简单的版本:第二种样式是 SAX 所尝试要做的更简单的版本. 让我们先研究树样式.假设我们要提取上一个示例中的同一个地址簿文档. 下面的示例来自我所创建的经修改的 eval.rb : 标准 eval.rb (链接到 Ruby 教程)可以根据对复杂对象的表达式求值

  • Ruby中使用Nokogiri包来操作XML格式数据的教程

    安装 对于Ubuntu,需要安装好 libxml2, libxslt 这两个组件: $ apt-get install libxml2 libxslt 然后就可以: $ gem install nokogiri 可选项 nokogiri提供了一些解析文件时的可选项,常用的有: NOBLANKS : 删除空节点 NOENT : 替代实体 NOERROR : 隐藏错误报告 STRICT : 精确解析,当解析到文件异常时抛出错误 NONET : 在解析期间禁止任何网络连接. 可选项使用方式举例(通过块

  • Ruby的XML格式数据解析库Nokogiri的使用进阶

    一.基础语法 1.直接以字符串形式获取nokogiri对象: html_doc = Nokogiri::HTML("<html><body><h1>Mr. Belvedere Fan Club</h1></body></html>") xml_doc = Nokogiri::XML("<root><aliens><alien><name>Alf</na

  • Ruby程序中创建和解析XML文件的方法

    使用builder创建XML builder安装方法: gem install builder require 'builder' x = Builder::XmlMarkup.new(:target => $stdout, :indent => 1) #":target =>$stdout"参数:指示输出内 容将被写向标准输出控制台 #":indent =>1"参数:XML输出形式将被缩 进一个空格字符x.instruct! :xml, :

  • 实例解析Ruby程序中调用REXML来解析XML格式数据的用法

    REXML 是由 Sean Russell 编写的库.它不是 Ruby 的唯一 XML 库,但它是很受欢迎的一个,并且是用纯 Ruby 编写( NQXML 也是用 Ruby 编写的, 但 XMLParser 封装了用 C 编写的 Jade 库). 在他的 REXML 概述中,Russell 评论道: 我有这样的问题:我不喜欢令人困惑的 API.有几种用于 Java 实现的 XML 解析器 API.其中大多数都遵循 DOM 或 SAX,并且在基本原理上与不断出现的众多 Java API 非常相似.

  • Ruby使用REXML库来解析xml格式数据的方法

    REXML 是一个完全用ruby写的processor ,他有多种api,其中两个经典的api是通过DOM-like 和SAX-like 来进行区分的.第一种是将整个文件读进内存,然后存储为一个分层的形式(也就是一棵树了).而第二种是"parse as you go",当你的文件很大,并且内存受到限制的时候,比较适合用这种. rexml具有如下特点: 100%用ruby编写 可以用来解析SAX和DOM 轻量,不足2000行代码 提供完整的API支持 ruby中内置 下面我们来看看如何使

  • 在Ruby中处理XML和XSLT以及XPath的简单教程

    什么是 XML ? XML 指可扩展标记语言(eXtensible Markup Language). 可扩展标记语言,标准通用标记语言的子集,一种用于标记电子文件使其具有结构性的标记语言. 它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言. 它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据. XML解析器结构和API XML的解析器主要有DOM和SAX两种. SAX解析器是基于事件处理的,需要从头到尾把XML文档扫描一遍,在扫描

  • php与XML、XSLT、Mysql的结合运用实现代码

    使用php中的xml与xslt要用到一些dll库, extension=php_domxml.dll //操作XML的函数库 extension=php_iconv.dll //转码用的,比如将GB2312的转成UTF-8的 extension=php_xslt.dll //XSLT的函数库 使用上面这三个库的时候,你要将php安装目录下的dlls目录加入到路径中,否则会找不到 这些类库的 在下面的课程中,我们会用到php中的PEAR类库,主要用了DB类库,Sql2XML类库,大家可以在 pea

  • Java中关于XML的API

    简单介绍一下Java关于xml的API,这样大家看到了缩写就知道是干什么的了.水平有限,多多包涵. 1.JAXP(Java API for XML Parsing) 2.JAXB(Java API for XML Binding) 3.JAXM(Java API for XML Messaging) 4.JAX-RPC(Java API for XML-RPC) 1.JAXP定义了在Java中使用DOM, SAX, XSLT的通用的接口.这样在你的程序中你只要使用这些通用的接口,当你需要改变具体

  • 对比DB2 9和DB2 V8.x中的XML功能

    正在看的db2教程是:对比DB2 9和DB2 V8.x中的XML功能. 简介 DB2 UDB Version 8.x 中的 XML 支持基于 DB2 的关系基础设施.XML 数据要么按原样存储为字符大对象(CLOB),要么分解到关系表中.另一方面,DB2 UDB Viper 具有真正的 XML 数据本机支持.现在,将 XML 数据作为一种新的数据类型处理,存储在一个经过解析并加上注释的树中,这个树是与关系数据存储分开的.还引入了基于 XML 模式的 XML 索引技术,并支持 XQuery 和 S

  • Python中的XML库4Suite Server的介绍

    在继续阅读本文之前,您务必要对我们在本专栏中将要讨论的一些技术有所了解.我们要使用的技术包括:可扩展的样式表语言转换(Extensible Stylesheet Language Transformations,XSLT).XML 路径语言(XML Path Language,XPath)和资源描述框架(Resource Description Framework,RDF).在 参考资料部分有到关于所有这些技术的信息的链接. 4Suite Server 概述 我们将使用由本文作者参与开发的 XM

  • 详细解读Python中解析XML数据的方法

    Python可以使用 xml.etree.ElementTree 模块从简单的XML文档中提取数据. 为了演示,假设你想解析Planet Python上的RSS源.下面是相应的代码: from urllib.request import urlopen from xml.etree.ElementTree import parse # Download the RSS feed and parse it u = urlopen('http://planet.python.org/rss20.xm

  • Java编程中更新XML文档的常用方法

    本文简要的讨论了Java语言编程中更新XML文档的四种常用方法,并且分析这四种方法的优劣.其次,本文还对如何控制Java程序输出的XML文档的格式做了展开论述. JAXP是Java API for XML Processing的英文字头缩写,中文含义是:用于XML文档处理的使用Java语言编写的编程接口.JAXP支持DOM.SAX.XSLT等标准.为了增强JAXP使用上的灵活性,开发者特别为JAXP设计了一个Pluggability Layer,在Pluggability Layer的支持之下,

  • ruby中执行周期性任务(定时任务)的3种方法

    1.前言 无论是用ruby做系统管理,还是用rails做web开发,都可能遇到周期性任务,它们按照一定时间周期(1小时,2天......)持续地触发.在ruby中,我认为一次性任务使用sidekiq来完成是非常方便的,而周期性的任务就需要用到whenever,sidetiq,clockwork等等gem了. 2.whenever 首先,whenever是基于linux的cron服务的,所以,在windows平台上没有直接的方法使用该gem.whenever严格来说应该算一个cron的翻译器,将r

  • ruby中并发并行与全局锁详解

    前言 本文主要给大家介绍了关于ruby并发并行和全局锁的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 并发和并行 在开发时,我们经常会接触到两个概念: 并发和并行,几乎所有谈到并发和并行的文章都会提到一点: 并发并不等于并行.那么如何理解这句话呢? 并发: 厨师同时接收到了2个客人点了的菜单需要处理. 顺序执行: 如果只有一个厨师,那么他只能一个菜单接着一个菜单的去完成. 并行执行: 如果有两个厨师,那么就可以并行,两个人一起做菜. 将这个例子扩展到我们的web开发

  • maven中pom.xml详细介绍

    POM 代表工程对象模型.它是使用 Maven 工作时的基本组建,是一个 xml 文件.它被放在工程根目录下,文件命名为 pom.xml. POM 包含了关于工程和各种配置细节的信息,Maven 使用这些信息构建工程. POM 也包含了目标和插件.当执行一个任务或者目标时,Maven 会查找当前目录下的 POM,从其中读取所需要的配置信息,然后执行目标.能够在 POM 中设置的一些配置如下: project dependencies plugins goals build profiles pr

随机推荐