Perlを用いて下のようなxml形式のデータから情報を得たいと考えています。


--------------------------
<name id="1">
<keywords>
<keyword>a</keyword>
<keyword>b</keyword>
</keywords>
</name>
<name id="2">
<keywords>
<keyword>c</keyword>
</keywords>
</name>
<name id="3">
<keywords>
<keyword>d</keyword>
</keywords>
</name>



------------------------------
このようなxmlがあったとき、name id 1と2と3を選んだら、
以下のようにキーワードの組み合わせを習得し、
テキストに書き込むプログラムを教えてください。
お願いします。

a-b
a-c
a-d
b-c
b-d
c-d

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2010/03/15 00:37:32
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:GreenStar No.1

回答回数192ベストアンサー獲得回数46

ポイント40pt

XML::Simpleを使った! コメントを全て外せばデバッグモード!!

#use Data::Dumper;
use XML::Simple;
@selectID = ('1', '2');
$readXML = XML::Simple -> new -> XMLin('a.xml', ContentKey => '-keywords', forcearray => 'keyword');
#warn Dumper($readXML);

@data = ();
foreach $id (@selectID) {
    foreach $values ($$readXML{'name'}{$id}{'keyword'}) {
        push(@data, @$values);
    }
}
#warn Dumper(@data);

$count = $#data;
open(OUT, ">a.txt");
for($i = 0; $i <= $count; $i++){
    for($k = $i + 1; $k <= $count; $k++){
        print OUT @data[$i] . '-' . @data[$k] . "\n";
    }
}
close(OUT);
<?xml version='1.0'?>
<root>
    <name id="1">
        <keywords>
            <keyword>a</keyword>
            <keyword>b</keyword>
        </keywords>
    </name>
    <name id="2">
        <keywords>
            <keyword>c</keyword>
        </keywords>
        </name>
    <name id="3">
        <keywords>
            <keyword>d</keyword>
        </keywords>
    </name>
</root>
id:riyoooh

早速のお返事ありがとうございます。

本当に助かりました。参考にさせていただきます。

ところが少し内容がことなるxmlに適用したところ、次のようなエラーが出てしまいました。

No such pseudo-hash field "40037221" at xml01.pl line9.

ことなるxmlというのは

<name id="1"> の部分が、

<researcher id="40037221" permalink="http://・・・">

のようになっています。

そこでいただいたプログラムの3行目のselectIDを40037221のようにし、

9行目のnameの部分をresearcherとしたところ上記のエラーが発生してしまいました。

このエラーの解決方法を教えていただけないでしょうか。

2010/03/14 19:14:24

その他の回答2件)

id:GreenStar No.1

回答回数192ベストアンサー獲得回数46ここでベストアンサー

ポイント40pt

XML::Simpleを使った! コメントを全て外せばデバッグモード!!

#use Data::Dumper;
use XML::Simple;
@selectID = ('1', '2');
$readXML = XML::Simple -> new -> XMLin('a.xml', ContentKey => '-keywords', forcearray => 'keyword');
#warn Dumper($readXML);

@data = ();
foreach $id (@selectID) {
    foreach $values ($$readXML{'name'}{$id}{'keyword'}) {
        push(@data, @$values);
    }
}
#warn Dumper(@data);

$count = $#data;
open(OUT, ">a.txt");
for($i = 0; $i <= $count; $i++){
    for($k = $i + 1; $k <= $count; $k++){
        print OUT @data[$i] . '-' . @data[$k] . "\n";
    }
}
close(OUT);
<?xml version='1.0'?>
<root>
    <name id="1">
        <keywords>
            <keyword>a</keyword>
            <keyword>b</keyword>
        </keywords>
    </name>
    <name id="2">
        <keywords>
            <keyword>c</keyword>
        </keywords>
        </name>
    <name id="3">
        <keywords>
            <keyword>d</keyword>
        </keywords>
    </name>
</root>
id:riyoooh

早速のお返事ありがとうございます。

本当に助かりました。参考にさせていただきます。

ところが少し内容がことなるxmlに適用したところ、次のようなエラーが出てしまいました。

No such pseudo-hash field "40037221" at xml01.pl line9.

ことなるxmlというのは

<name id="1"> の部分が、

<researcher id="40037221" permalink="http://・・・">

のようになっています。

そこでいただいたプログラムの3行目のselectIDを40037221のようにし、

9行目のnameの部分をresearcherとしたところ上記のエラーが発生してしまいました。

このエラーの解決方法を教えていただけないでしょうか。

2010/03/14 19:14:24
id:TREEG No.2

回答回数255ベストアンサー獲得回数34

ポイント20pt

誰も答えないので一応書いてみました。

ロジック間違ってたらすみません。

もっと良いやり方が絶対にありそうです。

use strict;

$| = 1;

#指定の番号を入れる

my @number = (1,2,3);


my @xml = <DATA>;

my @array; my $flag;

for my $number (@number){

for (@xml) {

if(m/<name id="${number}">/ || $flag){

if( my ($al) = ($_ =~ m!<keyword>(.*?)<\/keyword>!sig) ){

push(@array , $al );

}

$flag = 1;

}

if(m/<\/name>/){

$flag = 0;

}

}

}

for(;;){

for (@array) {

my $al1 = shift @array;

for my $al2 (@array){

open(F,">>text.txt");

print F "${al1}-${al2}\n";

print "${al1}-${al2}\n";

close(F);

}

}

unless(@array){last;};

}

__DATA__

<name id="1">

<keywords>

<keyword>a</keyword>

<keyword>b</keyword>

</keywords>

</name>

<name id="2">

<keywords>

<keyword>c</keyword>

</keywords>

</name>

<name id="3">

<keywords>

<keyword>d</keyword>

</keywords>

</name>

id:riyoooh

お返事おそくなりました。

早速試したところうまく動きました。

ありがとうございます。

2010/03/15 00:29:30
id:GreenStar No.3

回答回数192ベストアンサー獲得回数46

ポイント20pt

XMLファイルの構造が変わったのでプログラムを作り直しました! XMLに対して汎用的な対処法があれば私も知りたいです!!

#use Data::Dumper;
use XML::Simple;
@selectID = ('40037221', '40037222');
$readXML = XML::Simple -> new -> XMLin('a.xml', forcearray => 'keyword');
#warn Dumper($readXML);

@data = ();
foreach $id (@selectID) {
    $ref = $$readXML{'researcher'}{$id}{'keywords'}[0];
    foreach $values (@$ref{'keyword'}) {
        push(@data, @$values);
    }
}
#warn Dumper(@data);

$count = $#data;
open(OUT, ">a.txt");
for($i = 0; $i <= $count; $i++){
    for($k = $i + 1; $k <= $count; $k++){
        print OUT @data[$i] . '-' . @data[$k] . "\n";
    }
}
close(OUT);
<?xml version='1.0'?>
<root>
    <researcher id="40037221" permalink="http://example.jp/40037221">
        <keywords>
            <keyword>a</keyword>
            <keyword>b</keyword>
        </keywords>
    </researcher>
    <researcher id="40037222" permalink="http://example.jp/40037222">
        <keywords>
            <keyword>c</keyword>
        </keywords>
    </researcher>
    <researcher id="40037223" permalink="http://example.jp/40037223">
        <keywords>
            <keyword>d</keyword>
        </keywords>
    </researcher>
</root>
id:riyoooh

ありがとうございます。

xmlの形式が変わるごとに書き換えるのはめんどうですね。

2010/03/15 00:28:46

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

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

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

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

回答リクエストを送信したユーザーはいません