English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Ruby XML, XSLT と XPath チュートリアル

XMLとは何ですか?

XMLは拡張可能なマークアップ言語(eXtensible Markup Language)を指します。

拡張可能なマークアップ言語(XML)は、標準的な一般用途のマークアップ言語のサブセットであり、電子ファイルに構造を与えるためのマークアップ言語です。

それはデータをマークアップし、データの種類を定義し、ユーザーが自分のマークアップ言語を定義できるソース言語です。これは、アプリケーションや供給者に関係なく、構造化されたデータを描述し交換するための統一された方法を提供します。

さらに詳しい情報は、私たちの XML 教室

XML解析器の構造とAPI

XMLの解析器にはDOMとSAXの二種類があります。

  • SAXパーサーはイベント処理に基づいており、XMLドキュメントを一貫してスキャンする必要があります。スキャン中に、特定の構文構造に出会うたびに、その構文構造のイベントハンドラを呼び出し、アプリケーションにイベントを送信します。

  • DOM(Document Object Model)は、ドキュメントの階層的な構文構造を構築し、メモリ内にDOM木を構築します。DOM木のノードはオブジェクトの形で識別され、ドキュメントが解析された後、ドキュメントの全体のDOM木がメモリ内に配置されます。

RubyでのXMLの解析および作成

RubyでXMLのドキュメントの解析にはこのライブラリREXMLを使用できます。

REXMLライブラリはrubyのXMLツールキットで、純Ruby言語で書かれており、XMLに準拠しています1.0規格

Ruby1.8バージョンおよびその後、RUBY標準ライブラリにREXMLが含まれます

REXMLライブラリのパスは:rexml/document

すべてのメソッドとクラスはREXMLモジュールに統合されています

REXML解析器は他の解析器よりも以下の利点があります:

  • 100%がRubyで書かれています

  • SAXとDOM解析器に適用できます

  • 軽量で、不到2000行のコード

  • 簡単に理解できるメソッドとクラス

  • SAXに基づいて2 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
ルート要素: + root.attributes["shelf"]
 
root.attributes["shelf"]
xmldoc.elements.each("collection"/# 以下に映画のタイトルを出力します 
   movie"){ + |e| puts "映画のタイトル:" 
}
 
e.attributes["title"]
xmldoc.elements.each("collection"/movie/# 以下にすべての映画のジャンルを出力します
   |e| puts "映画のジャンル:" + e.text 
}
 
# 以下にすべての映画の説明を出力します
xmldoc.elements.each("collection"/movie/description") {
   |e| puts "映画の説明:" + e.text 
}

上記の例の出力結果は以下の通りです:

ルート要素:New Arrivals
映画のタイトル:Enemy Behind
映画のタイトル:Transformers
映画のタイトル:Trigun
映画のタイトル:Ishtar
映画のジャンル:戦争、サスペンス
映画のジャンル:アニメ、サイエンス・フィクション
映画のジャンル:アニメ、アクション
映画のジャンル:コメディ
映画の説明:アメリカについて話そう-日本戦争
映画の説明:科学的なファンタジー
映画の説明:Vash the Stampede!
映画の説明:見る価値のない退屈
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*$/     # 空白のみ
    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クラスをサポートしており、それは木構造の解析(ドキュメントオブジェクトモデル)に基づいています。

オンラインサンプル

#!/usr/bin/ruby -w
 
require 'rexml'/document'
include REXML
 
xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)
 
# 第1つの映画の情報
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'> ... </>
戦争、サスペンス
アニメ、サイエンスフィクション
アニメ、アクション
コメディ
["DVD", "DVD", "DVD", "VHS"]

XSLTとRuby

Rubyには2つのXSLTパーサーがあります。以下に簡単な説明を示します:

Ruby-Sablotron

このパーサーはMasayoshi Takahashiによって書かれ、保守されています。これは主にLinuxオペレーティングシステム用に書かれており、以下のライブラリが必要です:

  • Sablot

  • Iconv

  • Expat

以下の場所で使用できます。 Ruby-Sablotron これらのライブラリを見つけることができます。

XSLT4R

XSLT4RはMichael Neumannによって書かれており、XSLT4Rはシンプルなコマンドラインインタラクション用であり、XMLドキュメントの変換に使用されるサードパーティアプリケーションです。

XSLT4RはXMLScan操作が必要であり、XSLTを含んでいます。4Rアーカイブ、これは100%のRubyのモジュールです。これらのモジュールは標準のRubyインストール方法(即、Ruby install.rb)を使用してインストールできます。

XSLT4Rの语法フォーマットは以下の通りです:

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

アプリケーションでXSLTを使用したい場合4R、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 )

さらに詳細な情報