1. ホーム
  2. スクリプト・コラム
  3. ルビートピックス

Ruby は REXML ライブラリを使って xml 形式のデータをパースする

2022-01-31 07:58:39

REXMLは全てrubyで書かれた処理系で、いくつかのAPIを持っているが、そのうちの2つは古典的にDOMライクとSAXライクで区別される。最初のものは、ファイル全体をメモリに読み込んで、階層的な形(つまりツリー)で保存するものである。もう一つは "parse as you go" で、これはファイルが大きく、メモリに制約がある場合に適している。
rexmlには次のような特徴があります。

  • 100%Rubyで書かれています。
  • SAXやDOMのパースに使用できる
  • 2000行以下の軽量なコード
  • 完全なAPIサポートを提供
  • ルビーに組み込まれている

次のような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をパースする。

require 'rexml/document'
include REXML
xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)
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
}


XPATHを使用する。

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


念のため

追記:REXMLに関するセキュリティの問題
Rubyの公式サイトでは、8月23日にセキュリティ情報を掲載しました。http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/、Rubyが現在使用しているXML解析ライブラリREXMLは、再帰的要素がネストされたXMLファイルを解析する際にサービス拒否攻撃を受けます!再帰的要素がネストされたファイルは、サービス拒否攻撃の欠陥を発生し、サーバのリソースが不足する原因となります!RubyのXML解析は、再帰的要素を持つファイルを解析し、サービス拒否攻撃を受けます。
XMLファイルのパースを使用するRailsアプリケーションはすべてこの欠陥があり、修正する必要があります。Railsでの修正方法は以下の通りです。
1. Rails 2.0.2およびそれ以前のバージョン
ダウンロード ファイルを修正する をRAILS_ROOT/libディレクトリにコピーし、environment.rbに以下の記述を追加します。


require 'rexml-expansion-fix'

2. Rails 2.1.0以上
ダウンロード
ファイルを修正する のように、RAILS_ROOT/config/initializersディレクトリにコピーするだけです。