开发手册 欢迎您!
软件开发者资料库

Ruby - XML,XSLT和XPath教程

Ruby / XML,XSLT和XPath - 从简单和简单的步骤学习Ruby,从基本到高级概念,包括概述,环境设置,语法,类,变量,运算符,注释,If ... else,case,除非,循环,文件,I / O,函数,对象,TK,范围,迭代器,数组,字符串,方法,块,异常,面向对象,正则表达式,DBI,多线程,哈希,日期和时间,模块,LDAP,Web服务,网页编程,发送电子邮件,套接字编程,脚本语言,预定义常量,相关工具。

什么是XML?

可扩展标记语言(XML)是一种与HTML或SGML非常相似的标记语言.这是万维网联盟推荐的,可作为开放标准提供.

XML是一种可移植的开源语言,允许程序员开发可由其他应用程序读取的应用程序,无论操作系统和/或开发语言.

XML对于跟踪中小数据量非常有用,而不需要基于SQL的主干.

XML解析器体系结构和API

XML解析器有两种不同的口味 :

  • 类似SAX(流接口) : 在这里,您可以为感兴趣的事件注册回调,然后让解析器继续处理该文档.当文档很大或存在内存限制时,这很有用,它在从磁盘读取文件时解析文件,整个文件永远不会存储在内存中.

  • 类DOM(对象树接口) : 这是万维网联盟的建议,其中整个文件被读入内存并以分层(基于树)的形式存储,以表示XML文档的所有功能.

在使用大文件时,SAX显然无法像DOM一样快地处理信息.另一方面,专门使用DOM可以真正杀死你的资源,特别是如果在很多小文件上使用它.

SAX是只读的,而DOM允许更改XML文件.由于这两个不同的API在字面上相互补充,因此没有理由不将它们用于大型项目.

使用Ruby解析和创建XML

操纵XML的最常用方法是使用Sean Russell的REXML库.自2002年以来,REXML已成为标准Ruby发行版的一部分.

REXML是符合XML 1.0标准的纯Ruby XML处理器.它是一个非验证处理器,通过所有OASIS非验证一致性测试.

REXML解析器与其他可用解析器相比具有以下优点 :

  • 它是用Ruby编写的100%.

  • 它可以用于SAX和DOM解析.

  • 它是轻量级的,少于2000行代码.

  • 方法和类非常容易理解.

  • 基于SAX2的API和完整的XPath支持.

  • 附带Ruby安装,无需单独安装.

对于我们所有的XML代码示例,让我们使用一个简单的XML文件作为输入和减号;

         War, Thriller      DVD      2003      PG      10      Talk about a US-Japan war            Anime, Science Fiction      DVD      1989      R      8      A schientific fiction            Anime, Action      DVD      4      PG      10      Vash the Stampede!            Comedy      VHS      PG      2      Viewable boredom   

类DOM解析

让我们首先以树时尚解析我们的XML数据.我们首先要求 rexml/document 库;为方便起见,我们经常会使用REXML导入顶级命名空间.

#!/usr/bin/ruby -wrequire 'rexml/document'include REXMLxmlfile = File.new("movies.xml")xmldoc = Document.new(xmlfile)# Now get the root elementroot = xmldoc.rootputs "Root element : " + root.attributes["shelf"]# This will output all the movie titles.xmldoc.elements.each("collection/movie"){    |e| puts "Movie Title : " + e.attributes["title"] }# This will output all the movie types.xmldoc.elements.each("collection/movie/type") {   |e| puts "Movie Type : " + e.text }# This will output all the movie description.xmldoc.elements.each("collection/movie/description") {   |e| puts "Movie Description : " + e.text }

这将产生以下结果 :

Root element : New ArrivalsMovie Title : Enemy BehindMovie Title : TransformersMovie Title : TrigunMovie Title : IshtarMovie Type : War, ThrillerMovie Type : Anime, Science FictionMovie Type : Anime, ActionMovie Type : ComedyMovie Description : Talk about a US-Japan warMovie Description : A schientific fictionMovie Description : Vash the Stampede!Movie Description : Viewable boredom

类似SAX的解析

要处理相同的数据, movies.xml ,以面向流的方式文件我们将定义一个 listener 类,其方法将成为回调的目标来自解析器.

注意 : 不建议对小文件使用类似SAX的解析,这仅用于演示示例.

#!/usr/bin/ruby -wrequire 'rexml/document'require 'rexml/streamlistener'include REXMLclass 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}"   endendlist = MyListener.newxmlfile = 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

查看XML的另一种方法是XPath.这是一种伪语言,描述如何在XML文档中定位特定元素和属性,将该文档视为逻辑有序树.

REXML通过

#!/usr/bin/ruby -wrequire 'rexml/document'include REXMLxmlfile = File.new("movies.xml")xmldoc = Document.new(xmlfile)# Info for the first movie foundmovie = XPath.first(xmldoc, "//movie")p movie# Print out all the movie typesXPath.each(xmldoc, "//type") { |e| puts e.text }# Get an array of all of the movie formats.names = XPath.match(xmldoc, "//format").map {|x| x.text }p names

这将产生以下结果 :

 ... War, ThrillerAnime, Science FictionAnime, ActionComedy["DVD", "DVD", "DVD", "VHS"]

XSLT和Ruby

Ruby可以使用两种可用的XSLT解析器.这里给出了每个的简要说明.

Ruby-Sablotron

这个解析器由Masayoshi Takahashi编写和维护.这主要是为Linux操作系统编写的,需要以下库和减号;

  • Sablot

  • Iconv

  • Expat

您可以在 Ruby-Sablotron 找到此模块.

XSLT4R

XSLT4R由Michael Neumann编写,可以在XML下的Library部分的RAA中找到. 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_sxml_doc = File.readlines("document.xml").to_sarguments = { 'image_dir' => '/....' }sheet = XSLT::Stylesheet.new( stylesheet, arguments )# output to StdOutsheet.apply( xml_doc )# output to 'str'str = ""sheet.output = [ str ]sheet.apply( xml_doc )

进一步阅读

  • 有关REXML Parser的完整详细信息,请参阅标准文档 REXML分析器文档.

  • 您可以从 RAA存储库下载XSLT4R.