Ruby XML, XSLT 和 XPath 教程


什么是 XML ?

XML 指可扩展符号言语(eXtensible Markup Language)。

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

它能够用来符号数据、界说数据类型,是一种答运用户对自己的符号言语进行界说的源言语。 它十分合适万维网传输,供给一致的办法来描绘和交流独立于运用程序或供货商的结构化数据。

更多内容请检查咱们的 XML 教程


XML解析器结构和API

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

  • SAX解析器是根据事情处理的,需求自始至终把XML文档扫描一遍,在扫描的过程中,每次遇到一个语法结构时,就会调用这个特定语法结构的事情处理程序,向运用程序发送一个事情。
  • DOM是文档目标模型解析,构建文档的分层语法结构,在内存中树立DOM树,DOM树的节点以目标的方式来标识,文档解析文成今后,文档的整个DOM树都会放在内存中。

Ruby 中解析及创立 XML

RUBY中对XML的文档的解析能够运用这个库REXML库。

REXML库是ruby的一个XML东西包,是运用纯Ruby言语编写的,恪守XML1.0标准。

在Ruby1.8版别及其今后,RUBY标准库中将包括REXML。

REXML库的途径是: rexml/document

一切的办法和类都被封装到一个REXML模块内。

REXML解析器比其他的解析器有以下长处:

  • 100% 由 Ruby 编写。
  • 可适用于 SAX 和 DOM 解析器。
  • 它是轻量级的,不到2000行代码。
  • 很简略了解的办法和类。
  • 根据 SAX2 API 和完好的 XPath 支撑。
  • 运用 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编写和保护。这主要是为Linux188bet注册编写的,需求以下库:

  • Sablot
  • Iconv
  • Expat

你能够在 找到这些库。

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 )

更多材料

  • 完好的 REXML 解析器, 请检查文档 。

  • 你能够从 中下载 XSLT4R 。