Hatena::ブログ(Diary)

challenge Ruby on Rails

2010-04-23

REXML

[16]REXML

1.REXML

Ruby上で動作するXMLプロセッサで、ツリー解析とストリーム解析の両方の文書解析をサポートします。Ruby1.8からは標準添付されているライブラリです。

1-1.プロジェクトの生成

(1) プロジェクトAppli026を生成する

(2) 日本語環境の設定

(3) データベースの作成

テストをする場合はProject_testの環境で実施されるのでDBもそれに対応します。(db:create:allの指定)

NetBeansで[Rakeタスクを実行/デバッグ..]を選択します。

    フィルタ(F):

    パラメータ(P):

    一致するタスク(M):db:create:all

実行結果
(in D:/Rails_Projects/Appli026)

1-2.xmlファイルの作成

価格.comからサンプルデータを得て、次のようなxmlファイルを作成しましょう。

tvbest10.xml
<tv title="Best10"> <model name="ALF-4205DB (42)"> <maker>バイデザイン</maker><price>74,800</price><ranking>131</ranking> </model> <model name="REGZA 40A8000 (40)"> <maker>東芝</maker><price>78,000</price><ranking>7</ranking> </model> <model name="AQUOS LC-40AE6 (40)"> <maker>シャープ</maker><price>80,000</price><ranking>18</ranking> </model> <model name="REAL LCD-40MXW300 (40)"> <maker>三菱電機</maker><price>80,500</price><ranking>45</ranking> </model> <model name="BRAVIA KDL-40EX500 (40)"> <maker>SONY</maker><price>83,800</price><ranking>27</ranking> </model> <model name="TL42DZ1-B (42)"> <maker>ユニデン</maker><price>88,000</price><ranking>310</ranking> </model> <model name="AQUOS LC-40DS6 (40)"> <maker>シャープ</maker><price>89,800</price><ranking>30</ranking> </model> <model name="BRAVIA KDL-40V5 (40)"> <maker>SONY</maker><price>89,800</price><ranking>66</ranking> </model> <model name="REGZA 42C8000 (42)"> <maker>東芝</maker><price>91,200</price><ranking>123</ranking> </model> <model name="REGZA 40R9000 (40)"> <maker>東芝</maker><price>92,684</price><ranking>8</ranking> </model> </tv>

1-3.アプリケーションの作成

(1) コントローラの生成

NetBeansで[生成…]を選択します。

    ジェネレート(G): controller

    名前(N): xml

    ビュー(V):

実行結果
exists app/controllers/ exists app/helpers/ create app/views/xml exists test/functional/ create test/unit/helpers/ create app/controllers/xml_controller.rb create test/functional/xml_controller_test.rb create app/helpers/xml_helper.rb create test/unit/helpers/xml_helper_test.rb

(2) コントローラの編集

/app/controllers/xml_controller.rb
class XmlController < ApplicationController require "rexml/document" include REXML def index @doc = Document.new File.new("tvbest10.xml") end end

(3) ビューの作成

/app/views/xml/index.html.erb
<%=h @doc %>

(4) 動作確認

登録したxmlファイルが読み込まれることを確認するため、ブラウザからhttp://127.0.0.1:3000/xml/プログラムを起動します。

1-4.さまざまな機能

詳細な仕様はhttp://pub.cozmixng.org/~kou/rexml-doc-ja/でみることができますが、ここではその幾つかを紹介します。

(1) 要素の取り出し

/app/controllers/xml_controller.rb
class XmlController < ApplicationController require "rexml/document" include REXML def index @doc = Document.new File.new("tvbest10.xml") # 要素の取り出し @makers="" @doc.elements.each("tv/model/maker") { |element| @makers += element.to_s + "<br>" } end end


/app/views/xml/index.html.erb
<br/> makers<br/> --------<br/> <%= @makers %>


実行結果
makers ---------- バイデザイン 東芝 シャープ 三菱電機 SONY ユニデン シャープ SONY 東芝 東芝

(2) 属性の取り出し

/app/controllers/xml_controller.rb
class XmlController < ApplicationController require "rexml/document" include REXML def index @doc = Document.new File.new("tvbest10.xml") # 属性の取り出し @names="" XPath.each(@doc, "//model/attribute::name") { |element| @names += element.to_s + "<br>" } end end


/app/views/xml/index.html.erb
<br/> names<br/> --------
<%= @names %>


実行結果
names -------- ALF-4205DB (42) REGZA 40A8000 (40) AQUOS LC-40AE6 (40) REAL LCD-40MXW300 (40) BRAVIA KDL-40EX500 (40) TL42DZ1-B (42) AQUOS LC-40DS6 (40) BRAVIA KDL-40V5 (40) REGZA 42C8000 (42) REGZA 40R9000 (40)

(3) XMLの削除

/app/controllers/xml_controller.rb
class XmlController < ApplicationController require "rexml/document" include REXML def index @doc = Document.new File.new("tvbest10.xml") # XMLデータの削除 @doc.elements.delete("tv/model[1]") # modelという名の要素の中で一番目の要素を削除する end end


/app/views/xml/index.html.erb
doc<br> --------</br> <%=h @doc %>


実行結果(実際はベタ表示)
doc -------- <tv title='Best10'> <model name='ALF-4205DB (42)'> <maker>バイデザイン</maker><price>74,800</price><ranking>131</ranking> </model> <model name='REGZA 40A8000 (40)'> <maker>東芝</maker><price>78,000</price><ranking>7</ranking> </model> <model name='AQUOS LC-40AE6 (40)'> <maker>シャープ</maker><price>80,000</price><ranking>18</ranking> </model> <model name='REAL LCD-40MXW300 (40)'> <maker>三菱電機</maker><price>80,500</price><ranking>45</ranking> </model> <model name='BRAVIA KDL-40EX500 (40)'> <maker>SONY</maker><price>83,800</price><ranking>27</ranking> </model> <model name='TL42DZ1-B (42)'> <maker>ユニデン</maker><price>88,000</price><ranking>310</ranking> </model> <model name='AQUOS LC-40DS6 (40)'> <maker>シャープ</maker><price>89,800</price><ranking>30</ranking> </model> <model name='BRAVIA KDL-40V5 (40)'> <maker>SONY</maker><price>89,800</price><ranking>66</ranking> </model> <model name='REGZA 42C8000 (42)'> <maker>東芝</maker><price>91,200</price><ranking>123</ranking> </model> <model name='REGZA 40R9000 (40)'> <maker>東芝</maker><price>92,684</price><ranking>8</ranking> </model> </tv>

(4) XMLの更新

/app/controllers/xml_controller.rb
class XmlController < ApplicationController require "rexml/document" include REXML def index @doc = Document.new File.new("tvbest10.xml") # XMLデータの更新 @doc.elements["tv/model[@name='REGZA 40R9000 (40)']/price"].text = "91,500" # modelという要素のnameという属性が'REGZA 40R9000 (40)'である要素に含まれるpriceの値を # 91,500に変更する end end


/app/views/xml/index.html.erb
<br/> doc<br/> --------<br/> <%=h @doc %>


実行結果(実際はベタ表示)
doc -------- <tv title='Best10'> <model name='REGZA 40A8000 (40)'> <maker>東芝</maker><price>78,000</price><ranking>7</ranking> </model> <model name='AQUOS LC-40AE6 (40)'> <maker>シャープ</maker><price>80,000</price><ranking>18</ranking> </model> <model name='REAL LCD-40MXW300 (40)'> <maker>三菱電機</maker><price>80,500</price><ranking>45</ranking> </model> <model name='BRAVIA KDL-40EX500 (40)'> <maker>SONY</maker><price>83,800</price><ranking>27</ranking> </model> <model name='TL42DZ1-B (42)'> <maker>ユニデン</maker><price>88,000</price><ranking>310</ranking> </model> <model name='AQUOS LC-40DS6 (40)'> <maker>シャープ</maker><price>89,800</price><ranking>30</ranking> </model> <model name='BRAVIA KDL-40V5 (40)'> <maker>SONY</maker><price>89,800</price><ranking>66</ranking> </model> <model name='REGZA 42C8000 (42)'> <maker>東芝</maker><price>91,200</price><ranking>123</ranking> </model> <model name='REGZA 40R9000 (40)'> <maker>東芝</maker><price>91,500</price><ranking>8</ranking> </model> </tv>

(5) XMLの追加

/app/controllers/xml_controller.rb
class XmlController < ApplicationController require "rexml/document" include REXML def index @doc = Document.new File.new("tvbest10.xml") # XMLデータの追加 root = @doc.root model = Element.new "model" model.attributes["name"] = "AQUOS LC-40DS6 (40)" maker = Element.new "maker" price = Element.new "price" ranking = Element.new "ranking" model.add_element "maker" model.elements["maker"].text = "シャープ" model.add_element "price" model.elements["price"].text = "92,000" model.add_element "ranking" model.elements["ranking"].text = "30" root.add_element model end end


/app/views/xml/index.html.erb
<br/> doc<br/> --------<br/> <%=h @doc %>


実行結果(実際はベタ表示)
doc -------- <tv title='Best10'> <model name='REGZA 40A8000 (40)'> <maker>東芝</maker><price>78,000</price><ranking>7</ranking> </model> <model name='AQUOS LC-40AE6 (40)'> <maker>シャープ</maker><price>80,000</price><ranking>18</ranking> </model> <model name='REAL LCD-40MXW300 (40)'> <maker>三菱電機</maker><price>80,500</price><ranking>45</ranking> </model> <model name='BRAVIA KDL-40EX500 (40)'> <maker>SONY</maker><price>83,800</price><ranking>27</ranking> </model> <model name='TL42DZ1-B (42)'> <maker>ユニデン</maker><price>88,000</price><ranking>310</ranking> </model> <model name='AQUOS LC-40DS6 (40)'> <maker>シャープ</maker><price>89,800</price><ranking>30</ranking> </model> <model name='BRAVIA KDL-40V5 (40)'> <maker>SONY</maker><price>89,800</price><ranking>66</ranking> </model> <model name='REGZA 42C8000 (42)'> <maker>東芝</maker><price>91,200</price><ranking>123</ranking> </model> <model name='REGZA 40R9000 (40)'> <maker>東芝</maker><price>92,684</price><ranking>8</ranking> </model> <model name='AQUOS LC-40DS6 (40)'> <maker>シャープ</maker><price>92,000</price><ranking>30</ranking> </model> </tv>

(6) XMLの出力

/app/controllers/xml_controller.rb
class XmlController < ApplicationController require "rexml/document" include REXML def index @doc = Document.new File.new("tvbest10.xml") # XMLファイルの出力 File.open("tvbest11.xml","w") do |outfile| @doc.write(outfile) end end end


Open Flash Chart | index | 地図の表示 →