プログラミング的なSomething

プログラミング的なSomething

ITエンジニア(?)目線で生活・自転車・トレーニング話を綴ります

REXMLでのパース処理アレコレ−その2−

今回もREXMLを利用したパース処理についてまとめていきます。

やったこと

XMLファイルの生成
XMLファイルのコピー
XMLの要素を属性でソート

以上3点になります。

XMLファイルの生成

XML_output.rb

#XMLファイルを生成するスクリプトです
require 'rexml/document'

out_file_name = "output.xml"

doc = REXML::Document.new()
#Documentを生成
doc.add(REXML::XMLDecl.new(version="1.0",encoding="SHIFT_JIS"))
#DocumentにXML宣言を追加する。

root_element = REXML::Element.new("precure")
#precure要素を生成
doc.add_element(root_element)
root_element.add_text("precure:This is sample")
#precure要素をDocumentに追加して、データを入力する

root_element.add_attribute("no",1)
root_element.add_attribute("name","tsubomi")
#パラメータと属性を追加する

#output.xmlに書き込み
File.open(out_file_name,"w") do |outfile|
  doc.write(outfile,0)
end


#=>
#
#要素を追加
#<?xml version='1.0' encoding='SHIFT_JIS'?>
#<precure>
#precure:This is sample
#</precure>
#ファイルへは整形されて出力されません。最初は</precure>が見当たらず困惑。

#パラメータと属性の追加
#<?xml version='1.0' encoding='SHIFT_JIS'?>
#<precure no='1' name='tsubomi'>
#precure:This is sample
#</precure>

#今回は省略するが、要素や属性の削除はそれぞれ以下のように実装できる
#
#属性の削除
#root_element.delete_attribute('no')
#要素の削除
#root_element.delete_element(precure)

今回は地の文もコメントアウトしています。

XMLファイルのコピー

XML_copy.rb

#XMLファイルを丸ごとコピーするスクリプト
require 'rexml/document'

in_file_name = "sample1.xml"
out_file_name = "output.xml"

doc = nil
File.open(in_file_name) do |xmlfile|
  doc = REXML::Document.new(xmlfile)
end

#docインスタンスをまるごとoutput.xmlにコピー
out_doc = doc.deep_clone()

#ファイルにout_docを書きこむ
File.open(out_file_name,"w") do |outfile|
  out_doc.write(outfile,0)
end

#=>
#<?xml version='1.0' encoding='UTF-8'?> 
#<sample>
#<precure no='001' name='tsubomi'>
#blossom
#</precure>
#<precure no='002'>
#marine
#</precure>
#<precure no='003' name='itsuki'>
#sunshine
#</precure>
#</sample>
#
#改行は例によって行われないので少し長めです
#deep.clone()は子要素も含めて取得するときに使われます。
#今回のような場合には、out_docを用意しなくても、書きこむことができます

XMLの要素を属性でソート

#XMLファイルをソートするスクリプトです

require 'rexml/document'

xml_file_name = "sample1.xml"

#ファイルを開いてdocに値を持たせます
doc = nil
File.open(xml_file_name) do |xmlfile|
  doc = REXML::Document.new(xmlfile)
end

#ソートにHashを用いるため、precuresという名前でHashを生成する
precures = Hash.new

#配列のrootをsampleに格納する
sample = doc.root
sample.elements.each do |precure|
  #no属性を取得する
  no = precure.attributes.get_attribute("no").value
  #noをキーとする
  #今回はキーとなるnoをソートするだけの実装です
  precures[no] = precure
end

#Hashをソートしています
sorted = precures.sort
sorted.each do |key,no|
  #キーをnoとして各要素のnoを取得します
  attr_no = no.attributes.get_attribute("no")
  #ソートされた値を表示しています
  print(attr_no,"\n")
end

#=>
#002
#003
#101

以上です。
例によってサンプルのXMLファイルは
sample1.xml

<?xml version="1.0" encoding="UTF-8"?>
<sample>
 <precure no = "101" name = "tsubomi">blossom</precure>
 <precure no = "002" name = "erica">marine</precure>
 <precure no = "003" name = "itsuki">sunshine</precure>
</sample>

になります。
次はopen-uriライブラリを使って、実際にWEBAPIを使ったスクリプトを試してみます。

広告を非表示にする