プロが教えるわが家の防犯対策術!

XMLから行列を作成し、テキストに出力しようとしています。
XMLには複数人がそれぞれ好む色が書かれています。
それをもとに、以下のような行列を作りたいと考えています。

Perlのプログラムのコードを教えてください。よろしくおねがいします。

--------XML-------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<person_list>
<person id="1001">
<keywords><keyword>赤</keyword><keyword>青</keyword></keywords>
</person>
<person id="1002">
<keywords><keyword>赤</keyword><keyword>黄</keyword></keywords>
</person>
<person id="1003">
<keywords><keyword>黄</keyword></keywords>
</person>
</person_list>
------------------------------------------------------------------

--------テキスト-------------
1001 1002 1003
赤 1 1 0
青 1 0 0
黄 0 1 1
-----------------------------

A 回答 (2件)

while で読み込んで、それぞれの人単位に処理することになると思います。

人についてはその都度出力できますが、色についてはその都度出力できないので while ループが終わった後で出力することになります。なお、表示の関係で半角スペースを \x20 としていますが、実際のプログラムでは半角スペースで差し支えありません。

use strict;
my @result = (['赤'], ['青'], ['黄']);
print "\x20\x20";

while (<DATA>) {
if (/<person/ .. /<\/person>/) {
if (/id="(\d+)"/) {
printf "%5d", $1;
push @$_, "\x20\x20\x20\x200" foreach @result;
}
$result[0]->[-1] = "\x20\x20\x20\x201" if /<keyword>赤<\/keyword>/;
$result[1]->[-1] = "\x20\x20\x20\x201" if /<keyword>青<\/keyword>/;
$result[2]->[-1] = "\x20\x20\x20\x201" if /<keyword>黄<\/keyword>/;
}
}

print "\n";
print @$_, "\n" foreach @result;

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<person_list>
<person id="1001">
<keywords><keyword>赤</keyword><keyword>青</keyword></keywords>
</person>
<person id="1002">
<keywords><keyword>赤</keyword><keyword>黄</keyword></keywords>
</person>
<person id="1003">
<keywords><keyword>黄</keyword></keywords>
</person>
</person_list>

この回答への補足

ありがとうございます。
上の例ではうまくできました。

実際のデータは色データが1000種類ほどあるため、すべての色をプログラムに書くのが困難です。
このようなときに配列の色データを用いて手間を省く方法を教えていただけないでしょうか。

補足日時:2010/08/02 21:11
    • good
    • 0

前回のプログラムを修正してみました。

色データは冒頭の配列 @color に入れる形で、ファイル読み込み等でセットすればうまくいくものと思います。

use strict;
my @color = ('赤', '青', '黄');
my @result = map { [$_] } @color;
print "\x20\x20";

while (<DATA>) {
if (/<person / .. /<\/person>/) {
if (/id="(\d+)"/) {
printf "%5d", $1;
push @$_, "\x20\x20\x20\x200" foreach @result;
}
foreach my $i (0 .. $#color) {
$result[$i]->[-1] = "\x20\x20\x20\x201" if /<keyword>$color[$i]<\/keyword>/;
}
}
}

print "\n";
print @$_, "\n" foreach @result;

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<person_list>
<person id="1001">
<keywords><keyword>赤</keyword><keyword>青</keyword></keywords>
</person>
<person id="1002">
<keywords><keyword>赤</keyword><keyword>黄</keyword></keywords>
</person>
<person id="1003">
<keywords><keyword>黄</keyword></keywords>
</person>
</person_list>
    • good
    • 0
この回答へのお礼

なるほど。

ありがとうございました。

お礼日時:2010/08/03 11:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!