たのしいXML: RubyでXMLデータを扱う (12) 要素をソートして表示
sample12.rb

2008年02月10日(日)更新


■要素をソートして表示(sample12.rb)

たけち: 今回は、入力したXMLデータの要素をソートして表示してみよう。

さらら: あっ、はい。

たけち: 入力XMLファイルの要素をソートして出力XMLファイルをつくることをしたいんだけど、今回はその前に要素をソートして表示して見て、ソートの仕方の例を学んでおこうと思うんだ。

さらら: そうなんだ。


■読み込むXMLファイル

たけち: 読み込みXMLファイルはつぎのものを使うね。

  • 読み込みXMLファイル名 = sample12_in.xml
読み込みXMLファイル sample12_in.xml

<?xml version="1.0" encoding="utf-8" ?>
<manyo>
<poem no="0028" poet="持統天皇">春過ぎて夏来るらし白たえの衣干したり天の香具山</poem>
<poem no="0161" poet="持統天皇">北山にたなびく雲の青雲の星離り行き月を離れて</poem>
<poem no="0397" poet="笠郎女">奥山の岩本菅を根深めて結びし心忘れかねつも</poem>
<poem no="0408" poet="大伴家持">なでしこがその花にもが朝な朝な手に取り持ちて恋ひぬ日なけむ</poem>
<poem no="0599" poet="笠郎女">朝霧のおほに相見し人故に命死ぬべく恋ひわたるかも</poem>
<poem no="0611" poet="大伴家持">今さらに妹に逢はめやと思へかもここだ我が胸いぶせくあるらむ</poem>
<poem no="1353">石上布留の早稲田を秀でずとも縄だに延へよ守りつつ居らむ</poem>
<poem no="1616" poet="笠郎女">朝ごとに我が見る宿のなでしこの花にも君はありこせぬかも</poem>
<poem no="2540">振分けの髪を短み青草を髪にたくらむ妹をしぞ思ふ</poem>
<poem no="4516" poet="大伴家持">新しき年の初めの初春の今日降る雪のいやしけ吉事</poem>
</manyo>

さらら: 何人かの人の歌が並んでいるわね。あと、詠み人が分からない歌もあるわね。

たけち: そうだね。今回のソート表示の例では、

  • 歌人ごと、歌番号にソートして表示
  • 歌人の無い歌は表示しない
ということをやってみようね。

さらら: はい。

たけち: じゃ、いきなりだけど、具体的なソースコードの例を見てみよう。


■Rubyサンプルプログラム(12) sample12.rbのソースコード

Rubyサンプルプログラム(12) sample12.rb
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

require "rexml/document"
require "kconv"

xml_file_name = "sample12_in.xml"

doc = nil
File.open(xml_file_name) {|xmlfile|
  doc = REXML::Document.new(xmlfile)
}

print("--- ", xml_file_name, " ---\n\n")
# Hash(ハッシュ)を生成
poems = Hash.new

sample = doc.root
sample.elements.each { |poem|
  no =poem.attributes.get_attribute("no").value

  attr_poet = poem.attributes.get_attribute("poet")
  if attr_poet != nil then
    poet = attr_poet.value.tosjis
    poems[poet + no] = poem
  end
}
# poem要素をソート
sorted = poems.sort
sorted.each {|key, poem|
  attr_poet = poem.attributes.get_attribute("poet")
  attr_no = poem.attributes.get_attribute("no")
  print(attr_poet.value.tosjis," ", attr_no," ", poem.text.tosjis, "\n")
}


※ここでは、文字コードをutf-8としてsample12.rbを作成しています。

さらら: 長いわね。(^ ^;

たけち: 今回のサンプルでは、Hash(ハッシュ)を使っているよ。

さらら: Hash(ハッシュ)ってなに?

たけち: これを使うと簡単にキーでソートできるんだよ。今回の例では

  • キー = 歌人 + 歌番号
  • 値 = poem要素
としているからね。

さらら: そうなんだ。


※Hash(ハッシュ)については、Rubyのサイトや書籍を参照してくださいね。

たけち: 簡単にソースコードの説明をしておくね。まずは、13行目で、Hashを生成しているね。ここでは、まだ、Hashの中身は空(から)だからね。

さらら: はい。

たけち: 16〜22行目で、読み込んだXMLファイルのpoem要素を順にHash(ハッシュ)に追加しているね。で、22行目で、poem要素をHash(ハッシュ)に追加しているんだよ。
    poems[poet + no] = poem

さらら: そうなんだ。キーが、poet + no = poemってとこなのかしら。。

たけち: そうそう。で、26行目で、キーでソートしているんだよ。
sorted = poems.sort

さらら: あら、それだけでいいの?

たけち: そうそう。意外に簡単でしょ。

さらら: そうね。Hashに追加するのが面倒だけど。。。

たけち: そうそう。で、27〜31行目で、ソートされたHashから順にキーと要素(poem)を取り出して表示しているよ。

さらら: "なんとか.each" って前にもあったわね。そのときはHashじゃなかったけど。


■サンプルプログラムsample12.rbの実行結果の確認

たけち: じゃ、このsample12.rbを実行した結果をみてみよう。コマンドプロンプトウィンドウで

  • ruby sample12.rb

と入力してみて。

さらら: はい。

sample12.rbの実行結果確認

さらら: 歌人の名前と歌番号の後に、歌の内容が表示されているわ。それに、歌人順、歌番号順に。

たけち: ちゃんと実行できたみたいだね。

さらら: これを見て、やっと分かった気がするわ。

たけち: 今回のサンプルを踏まえて、次回は、入力XMLファイルを元に、歌人ごと、歌番号順にソートして出力XMLファイルを作ってみようね。

さらら: あっ、はい。そういうことね。

 → 次回は要素をソートして出力 sample13.rbです。 (^ ^;


[たのしいXML のインデックス]へ