Ruby XML、XSLT、および XPath のチュートリアル
XML とは何ですか?
XML は eXtensible Markup Language を指します。
Extensible Markup Language は、標準ユニバーサル マークアップ言語のサブセットであり、電子ドキュメントをマークアップして構造化するために使用されるマークアップ言語です。
データのマーク付けとデータ型の定義に使用でき、ユーザーが独自のマークアップ言語を定義できるようになります。 これは World Wide Web トランスポートに最適であり、アプリケーションやベンダーに依存せずに構造化データを記述および交換するための統一されたアプローチを提供します。
詳細については、XML チュートリアルをご覧ください
XML パーサーの構造と API
XML パーサーには、DOM と SAX の 2 つの主要なタイプがあります。
SAX パーサーはイベント処理に基づいており、スキャン プロセス中に文法構造が見つかるたびに、この特定の文法構造のイベント ハンドラーが呼び出されます。イベントをアプリケーションに送信します。
DOM は、ドキュメントの階層構文構造を構築し、メモリ内に DOM ツリーを作成するドキュメント オブジェクト モデルの解析です。ドキュメントの解析が完了すると、DOM ツリーのノードがオブジェクトの形式で識別されます。ドキュメントの DOM ツリー全体がメモリ内に配置されます。
Ruby での XML の解析と作成
RUBY は、このライブラリ REXML ライブラリを使用して XML ドキュメントを解析できます。
REXML ライブラリは、純粋な Ruby 言語で書かれており、XML1.0 仕様に準拠しています。
Ruby バージョン 1.8 以降では、REXML が RUBY 標準ライブラリに含まれます。
REXML ライブラリのパスは次のとおりです: rexml/document
すべてのメソッドとクラスは REXML モジュールにカプセル化されます。
REXML パーサーには、他のパーサーに比べて次の利点があります:
100% が Ruby で書かれています。
SAX および DOM パーサーで動作します。
これは軽量で、コードは 2000 行未満です。
メソッドとクラスは非常に理解しやすいです。
SAX2 API と完全な XPath サポートに基づいています。
個別にインストールするのではなく、Ruby のインストールを使用してください。
以下は、movie.xml として保存されたサンプルの 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 パーサー
は同じデータ ファイル movie.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 チュートリアルを参照)。
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 には 2 つの XSLT パーサーがあり、簡単に説明します。
Ruby-Sablotron
このパーサーは、Takahash 正義判事によって作成および保守されています。これは主に Linux オペレーティング システム用に書かれており、次のライブラリが必要です:
Sablot
Iconv
Expat
これらのライブラリは Ruby-Sablotron で見つけることができます。
XSLT4R
XSLT4R は Michael Neumann によって書かれています。 XSLT4R は、単純なコマンド ライン操作に使用され、サードパーティ アプリケーションで XML ドキュメントを変換するために使用できます。XSLT4R には XMLScan 操作が必要で、100% Ruby モジュールである XSLT4R アーカイブが含まれています。これらのモジュールは、標準の 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 パーサーについては、REXML パーサーのドキュメントを参照してください。
XSLT4R は RAA ナレッジベースからダウンロードできます。