XMLファイルの属性値を一覧にするPerlスクリプトを作りたいです。

(XMLファイル毎の違いを見るために一覧化したいです)

XML::DOMを使用すればできそうですが、「Perl + XML::DOM」についての参考になるサイトを教えて下さい。
(できれば日本語でお願いします)

作りたいものは、下のようなXMLファイルから、【実行結果】を出力したいです。XMLファイルは複数あり、タグの要素名や要素数、属性値は一定ではありません。

よろしくお願いします。

【XMLファイル】
<?xml version="1.0" encoding="utf-8"?>
<root>
<entry>
<id attr_id="10" attr_id="20"></id>
<name>
<name1 attr_name1="AA"></name1>
<name2 attr_name2="BB"></name2>
</name>
<age attr_age="20"></age>
<comment attr_comment="ABC"></comment>
</entry>
<log maxSize="32KB" ratate="3">
</log>
</root>

【実行結果】
root,entry,id:attr_id="10";attr_id="20"
root,entry,name,name1:attr_name1="AA"
root,entry,name,name2:attr_name2="BB"
root,entry,age:attr_age="20"
root,entry,comment:attr_comment="ABC"
root,log:maxSize="32KB";ratate="3"

回答の条件
  • 1人10回まで
  • 登録:2006/07/11 15:25:13
  • 終了:2006/07/18 15:30:03

回答(4件)

id:kidd-number5 No.1

kidd-number5回答回数117ベストアンサー獲得回数152006/07/11 17:35:51

ポイント23pt

DOMはXMLの構造がわかっている場合に使う方が便利なので、今回の場合はSAXの方が良いです。

完成系ではなくて申し訳ないですがSAXによるサンプルを書いてみたので参考にしてみてください。

use XML::Parser;
sub start_handler{
  shift;
  $element = shift;
  @attrs = shift;
  @values = shift;
  print "$element start\n";
  for($i=0; $i < length(@attrs); $i++){
    print "\t$attrs[i]=$values[i]\n";
  }
}
sub end_handler{
  shift;
  $element = shift;
  
  print "$element end\n";
  
}
$parser = new XML::Parser;
$parser->setHandlers(
  Start => \&amp;start_handler,
  End => \&amp;end_handler,
);
$parser->parsefile('test.xml');
id:zero4

ありがとうございます。SAXについては今本を読んで確認中です。また書きます。

追記

@attrs = shift;

@values = shift;

とすると複数の属性に対応できないようですね。今対応中。

WEBの情報がなかなか見つけられないです。javaなら見つけられるんですが、オライリーの本も読みたい。

2006/07/12 00:17:03
id:kidd-number5 No.2

kidd-number5回答回数117ベストアンサー獲得回数152006/07/12 16:56:10

ポイント23pt

そうですね。。。確かに見つかりません。

PHP/Javaだったらある程度あるんですけどね・・・すみません。

(あと、Perlの文法に詳しいわけではないので、shiftのあたり、うまくなかったのも容赦ください)

ちなみに

 <id attr_id="10" attr_id="20">

はそもそも同じ属性名で値を二つ持っているのですが、これってXML的にvalidではないのだと思いますが・・・。それが複数属性対応できない原因になっているということはないのでしょうか。

(んー、二回までの回答なのでこれで終わり・・・)

id:zero4

kidd-number5さん ご回答ありがとうございます。kidd-number5さんのコードのおかげでデータを取るところまでできました。詳細はまた書きます。回答数も増やしますので何かあれば何でも書いてください。

2006/07/12 17:16:58
id:kidd-number5 No.3

kidd-number5回答回数117ベストアンサー獲得回数152006/07/12 18:19:24

ポイント22pt
use XML::Parser;

local @elements;

sub start_handler{
  shift;
  $elem = shift;
  %attrs = @_;
  push(@elements, $elem);
  
  for($i=0;$i < $#elements;$i++){
    print "$elements[i].";
  }
  print "$elements[$#elements]:";
  while(($name, $value) = each(%attrs)){
    print "$name=$value;";
  }
  
  print "\n";
}

sub end_handler{
  shift;
  $element = shift;
  pop(@elements);
  
}

$parser = new XML::Parser;
$parser->setHandlers(
  Start => \&amp;start_handler,
  End => \&amp;end_handler,
);
$parser->parsefile('test.xml');

属性のない値も今のところ出ちゃいますがこれでどうかしら?

結果

root:
root.entry:
root.root.id:attr_id2=100;attr_id1=10;
root.root.name:
root.root.root.name1:attr_name1=AA;
root.root.root.name2:attr_name2=BB;
root.root.age:attr_age=20;
root.root.comment:attr_comment=ABC;
root.log:maxSize=32KB;ratate=3;
id:zero4

あ すごい! 家に帰ってから確認させて頂きます。ありがとうございます。 また書きます。

2006/07/12 19:32:59
id:kidd-number5 No.4

kidd-number5回答回数117ベストアンサー獲得回数152006/07/12 19:54:32

ポイント22pt

あ、、、気づかれたかもしれませんが

誤)print "$elements[i].";

正)print "$elements[$i].";

ですね。

なんか結果が変だと思ったら・・・。

id:zero4

わざわざありがとうございます。さくら水産で飲んで今帰って来たので、また後で書きます。

追記

試しました。この出力結果だと加工が簡単にできそうです。ありがとうございます!

XMLファイルの加工?プログラム楽しくなってきました。RSS化とかして遊んでます。perlの情報少ないのでどっかで書きます。

2006/07/14 01:00:49

コメントはまだありません

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません