┌──────────┐
│PerlでXMLを使う   │
│(1)まずは使ってみる │
│2005/01/22     │
└──────────┘

●今回の趣旨

 ・Monpeの主観ですが、XMLは非常に便利なデータ記述言語です。XMLの便利さは以下
  の点に特徴付けられます。
  ┌────────────────────────────────────┐
   1)データ自体に構造が定義できる
   2)構造記述(タグ)は自由に定義できる
   3)事実上、データ記述言語として標準化されつつある
  └────────────────────────────────────┘

 ・そしてテキストデータを気軽に扱うことができる言語と言えばPerlです。今回は
  XMLとPerlを組み合わせて、構造化データのハンドリングにチャレンジしてみたい
  と思います。
 
 ・尚、Perlのレベルとしては「リファレンスとデータ構造」を理解していることが前
  提です。
  
 
●初めにXMLとは

 ◆歴史的経緯から
 
  ・XML...eXtensible Markup Language は、マークアップ言語です。
  
  ・もともとマークアップ言語としての大御所は1986年にISOで制定されたSGML
   (Standard Gneralized Markup language)です。厳密にはマークアップ言語を設
   計するためのルールであると言えます。
  
  ・SGMLの目的は、端的に言えば「データと表示の分離」にあったと考えられます。
   つまりデータに対しては純粋に中身と構造のみが記述され、表示に関する記述は
   完全に切り離すというものです。
  
  ・この「データと表示の分離」が可能であれば、同じデータソースを異なるプログ
   ラムで共有することが可能になります。コンピュータで個人が大量のデータを管
   理することが当たり前となった現在では、このことにどれだけの利点があるかは
   明白です。
  
  ・しかしながらSGMLが制定された当時...1980年代、SGML稼働環境を整備するには
   強烈なコストがかかるであろうことも容易に想像できるでしょう。つまりSGMLは
   普及しなかったのです。
  
  ・その後SGMLのルールに則ってタグ設計されたHTML(HyperText Markup Language)
   が登場しました。この言語がWEB上でのデータ表示でパワーを発揮し、マークア
   ップ言語の便利さを世に知らしめることになりましたが、実は「データと表示の
   分離」というSGMLの理念は置き去りになっていました。
  
  ・そこで、SGMLでの構造定義記述とHTMLの容易さを併せ持つ言語としてXMLが考案
   されました。つまりXMLになってようやく「汎用的データ記述言語」としての体
   裁が整ったというわけです。

 ◆XMLの例
 
  ・XMLは記述方式にいろいろなルールがあり、XML文書の構成定義やデータのリンク
   など様々な機能に及びます。
  
  ・ですが、本レポートではPerlからXMLデータを扱う点に主眼を置いているので、
   XML記述方式の詳しい解説については、別へ譲り、ここでは簡単な例のみを扱う
   こととします。
  
  ・まず下記の例を見て下さい。
  
  [List1. XMLの例]
  ┌────────────────────────────────────┐
   [名簿:通常テキスト]    | [XML表記]
                |
    Name : Ichiro Suzuki   | <NameList>
    Tel : 090-1111-1111   |  <Member>
    Mail : itiro@hoge.co.jp |   <Name>Ichiro Suzuki</Name>
                |   <Tel>090-1111-1111</Tel>
    Name : Jiro Sato     |   <Mail>itiro@hoge.co.jp</Mail>
    Tel : 090-2222-2222   |  </Member>
    Mail : jiro@hoge.co.jp  |  <Member>
                |   <Name>Jiro Sato</Name>
    Name : Sabro Yamada   |   <Tel>090-2222-2222</Tel>
    Tel : 090-3333-3333   |   <Mail>jiro@hoge.co.jp</Mail>
    Mail : sabro@hoge.co.jp |  </Member>
                |  <Member>
                |   <Name>Sabro Yamada</Name>
                |   <Tel>090-3333-3333</Tel>
                |   <Mail>sabro@hoge.co.jp</Mail>
                |  </Member>
                | </NameList>
                |
  └────────────────────────────────────┘
 
  ・左側が通常のテキスト。右側がデータ構造をXML記述した一例です。データを記
   述するためのタグには特に規定が無く、好みで勝手に決めています。今回の例で
   は以下のタグ構造になっています。
  
    <NameList>   <--- 名簿全体
     |
     +-<Member>  <--- 各人のデータ単位
     |  +-<Name> <--- 氏名
     |  +-<Tel>  <--- 電話
     |  +-<Mail> <--- メールアドレス
     :
     +-<Member>
     :   :
     


●入門:PerlとXML

 ◆最もシンプルな例
 
  ・もし、このXMLデータを読み込むための何かを今から作るのであれば大変です。
   自分で作るぐらいなら、XMLではなくCSVで書いたほうが全然簡単です。
  
  ・それでもXMLを推すのは、当然XMLを扱うためのツールが存在しているからです。
   Perlの良いところは無償で利用できるライブラリ/モジュールが豊富であるとこ
   ろですが、当然この中にはXMLを扱うものも含まれています。
  
  ・最初に使うのは XML::Simple です。標準とは言えないのですが、簡単に使える
   と言う意味で、これから紹介していきたいと思います。

 ◆XMLデータの読み込み
  
  ・はじめに先ほど作成したXMLデータを読み込んでみます。読み込みでは
   XML::Simpleモジュールの XMLin() を使用します。
  
  [List2. XMLデータの読み込み]
  ┌────────────────────────────────────┐
   #! perl -w
  
   use XML::Simple;  # XML::Simpleモジュールの読み込み
   use Data::Dumper;  # Data構造表示用モジュールの読み込み
   use strict;
  
   my $rData = XMLin('./test.xml'); # XMLデータ読み込み & リファレンス受け
  
   print Dumper($rData);
  
   for (my $i=0; $i<=$#{$rData->{Member}}; $i++) {
     my $rMember = $rData->{Member}->[$i];
     foreach my $ele (keys(%{$rMember})) {
       print "$i : $ele :",$rMember->{$ele},"\n";
     }
   }
  └────────────────────────────────────┘
  ┌────────────────────────────────────┐
  [出力結果]
   $VAR1 = {
     'Member' => [
       { # Member要素[0]
         'Tel' => '090-1111-1111',
         'Mail' => 'itiro@hoge.co.jp',
         'Name' => 'Ichiro Suzuki'
       },
       { # Member要素[1]
        'Tel' => '090-2222-2222',
        'Mail' => 'jiro@hoge.co.jp',
        'Name' => 'Jiro Sato'
       },
       { # Member要素[3]
        'Tel' => '090-3333-3333',
        'Mail' => 'sabro@hoge.co.jp',
        'Name' => 'Sabro Yamada'
       }
     ]
   };
   
   0 : Tel :090-1111-1111
   0 : Mail :itiro@hoge.co.jp
   0 : Name :Ichiro Suzuki
   1 : Tel :090-2222-2222
   1 : Mail :jiro@hoge.co.jp
   1 : Name :Jiro Sato
   2 : Tel :090-3333-3333
   2 : Mail :sabro@hoge.co.jp
   2 : Name :Sabro Yamada
  └────────────────────────────────────┘
 
  ・このサンプルコードでわかると思いますが、XML::Simpleでは、XMLデータをハッ
   シュ構造データとして読み込みます。そして同一タグのデータが複数存在する場
   合は、配列として処理されます。
  
  ・この場合はルートタグ<NameList>の下に<Member>が複数あるので、これは配列に
   なります。各配列はTel/Mail/Name要素を持つハッシュへの参照を受けています。
   
     $rData->{Member}->[1] = {
                   Tel => '090-2222-2222',
                   Mail => 'jiro@hoge.co.jp',
                   Name => 'Jiro Sato'
                 }

 ◆XMLデータの書き出し
 
  ・読み込み時と同様なデータ構造を作ることで、XMLデータを書き出すこともでき
   ます。書き出しには XML::Simple の XMLout() を使用します。
  
  ・例として上記コードにデータを追加し、XMLとして書き出してみます。尚データ
   を簡単化するため、今回のリストではXMLin()実行時にforcearrayオプションを
   付けています。このオプションを付けるとデータ要素の数が単一でもリストして
   扱うようになります。
  
  [List2. XMLデータの読み込み]
  ┌────────────────────────────────────┐
   #! perl -w
  
   use XML::Simple;
   use strict;
  
   my $rData = XMLin('./test.xml', forcearray=>1);
  
   my $rAddData = {
       Name => ['Siro Yamamoto'], # 単一要素もリストに
       Tel => ['090-4444-4444'],
       Mail => ['siro@hoge.co.jp']
    };
  
   push(@{$rData->{Member}}, $rAddData); # データを追加
  
   open(FH, "> test_add.xml");
     print FH XMLout($rData);
     print FH "\n";
   close(FH);
  └────────────────────────────────────┘
  ┌────────────────────────────────────┐
  [出力結果 (test_add.xmlの中身です)]
   <opt>
    <Member>
     <Mail>itiro@hoge.co.jp</Mail>
     <Name>Ichiro Suzuki</Name>
     <Tel>090-1111-1111</Tel>
    </Member>
    <Member>
     <Mail>jiro@hoge.co.jp</Mail>
     <Name>Jiro Sato</Name>
     <Tel>090-2222-2222</Tel>
    </Member>
    <Member>
     <Mail>sabro@hoge.co.jp</Mail>
     <Name>Sabro Yamada</Name>
     <Tel>090-3333-3333</Tel>
    </Member>
    <Member>
     <Mail>siro@hoge.co.jp</Mail>
     <Name>Siro Yamamoto</Name>
     <Tel>090-4444-4444</Tel>
    </Member>
   </opt>
  └────────────────────────────────────┘

  ・このようにXML用のモジュールを使用すれば、XMLデータをそのまま構造化された
   データとして直接入出力することが可能です。
  
  ・これはデータ処理ツールを作る側から見ると、非常に便利な機能です。最初から
   構造化されていることは大きな利点であり、あるデータを多人数/多階層で処理
   を重ねる場合等は絶大な効果を発揮します。
  
  ・これで、とりあえずはPerlでXMLデータをハンドリングする感触が掴めたと思い
   ます。データ構造がシンプルであれば、今回のレポート(XML::Simple)だけでも
   十分役に立つでしょう。
  
  ・次回からはより細かい処理が可能なモジュールやクラス、インタフェースについ
   て解説をしたいと思います。


[▲Perl Home▲]


Copyright(c)2005 Monpe
All Rights Reserved