人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

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"

●質問者: zero4
●カテゴリ:コンピュータ インターネット
✍キーワード:AA ABC BB DOM name
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● kidd-number5
●23ポイント

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');
◎質問者からの返答

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

追記

@attrs = shift;

@values = shift;

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

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


2 ● kidd-number5
●23ポイント

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

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

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

ちなみに

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

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

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

◎質問者からの返答

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


3 ● kidd-number5
●22ポイント
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;
◎質問者からの返答

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


4 ● kidd-number5
●22ポイント

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

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

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

ですね。

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

◎質問者からの返答

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

追記

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

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

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ