Perlを用いて、XMLファイルの中のキーワードの個数を数えるプログラムを組もうと思っています。
次のようなXMLの中の<keyword>のタグに囲まれた文字列を数えるプログラムです。
<?xml version="1.0" encoding="UTF-8"?>
<grant_award_list>
<grant_award id="1001">
<title>タイトル1</title>
<keywords><keyword>A</keyword><keyword>B</keyword></keywords>
</grant_award>
<grant_award id="1002">
<title>タイトル2</title>
<keywords><keyword>B</keyword></keywords>
</grant_award>
</grant_award_list>
このようなときに、次のようにキーワードとその出現回数が記載されたXMLファイルにしたいと考えています。
<?xml version="1.0" encoding="UTF-8"?>
<keywords>
<keyword>A</keyword>
<count>1</count>
</keywords>
<keywords>
<keyword>B</keyword>
<count>2</count>
</keywords>
具体的なプログラムのコードを教えてください。よろしくお願いします。
No.1
- 回答日時:
表示がくずれるので、以下、スペース2文字を全角のスペースにして書いてあることに注意
use XML::TreePP;
my $file = shift || 'tmp.xml';
my $tpp = XML::TreePP->new( utf8_flag => 1 );
my $tree_in = $tpp->parsefile($file);
my %count_of = ();
for my $hash_ref ( @{ $tree_in->{grant_award_list}->{grant_award} } ) {
my $keyword = $hash_ref->{keywords}->{keyword};
if ( ref($keyword) eq 'ARRAY' ) {
for my $item ( @{$keyword} ) {
$count_of{$item}++;
}
}
else {
$count_of{$keyword}++;
}
}
my $tree_out;
my $index = 0;
while ( my ( $keyword, $count ) = each %count_of ) {
$tree_out->{keywords}->[$index]->{keyword} = $keyword;
$tree_out->{keywords}->[$index]->{count} = $count;
$index++;
}
my $xml = $tpp->write($tree_out);
print $xml;
この回答への補足
早速のお返事ありがとうございます。
<keyword>ではさまれた要素に漢字やひらがなを含んでいるため、文字化けしてしまいました。
どのようにすれば解決できますでしょうか。
よろしくお願いいたします。
No.2
- 回答日時:
use XML::TreePP;
use Encode;
my $file = shift || 'tmp.xml';
my $tpp = XML::TreePP->new( utf8_flag => 1 );
my $tree_in = $tpp->parsefile($file);
my %count_of = ();
for my $hash_ref ( @{ $tree_in->{grant_award_list}->{grant_award} } ) {
my $keyword = $hash_ref->{keywords}->{keyword};
if ( ref($keyword) eq 'ARRAY' ) {
for my $item ( @{$keyword} ) {
$count_of{$item}++;
}
}
else {
$count_of{$keyword}++;
}
}
my $tree_out;
my $index = 0;
while ( my ( $keyword, $count ) = each %count_of ) {
$tree_out->{keywords}->[$index]->{keyword} = $keyword;
$tree_out->{keywords}->[$index]->{count} = $count;
$index++;
}
# encoding="UTF-8" なのでutf8で出力する。
my $xml = encode( "utf8", $tpp->write($tree_out) );
print $xml;
No.3ベストアンサー
- 回答日時:
最後にutf8で出力しているところで文字化けしているんじゃないですか?
cp932、shiftjis、eucjpなど適切なエンコードを指定して下さい。
あまり関係ないけどちょっと書き直し(全角空白あり注意)
use XML::TreePP;
use Encode;
my $file = shift || 'tmp.xml';
my $tpp = XML::TreePP->new( utf8_flag => 1, force_array => ['keyword'] );
my $tree_in = $tpp->parsefile($file);
my %count_of = ();
for my $hash_ref ( @{ $tree_in->{grant_award_list}->{grant_award} } ) {
my $keyword = $hash_ref->{keywords}->{keyword};
for my $item ( @{$keyword} ) {
$count_of{$item}++;
}
}
my $tree_out = {};
$tree_out->{keywords}
= [ map { { keyword => [$_], count => $count_of{$_} } } keys %count_of ];
my $xml = encode( "utf8", $tpp->write($tree_out) );
print $xml;
この回答への補足
何度もありがとうございます。
cp932、shiftjis、eucjpなど試してみましたが、どれも文字化けしてしまいました。
XMLファイルの保存形式や文字コードも確認しましたが、やはり無理でした。
コマンドプロンプトによる表示が原因でした。
頂いたプログラムによってXMLファイルを生成したら、正常に表示されていました。
本当にありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- MySQL my_itemsテーブルのIDにAUTO_INCREMENT を追加ができるかで 1 2023/01/03 09:09
- Visual Basic(VBA) Excelで下記のようにマクロを作ったところ、一回目は実行できたのですが、二回目以降「実行時エラー1 1 2022/03/25 08:08
- Visual Basic(VBA) Excel VBA キーワードから列を取得して、さらに空欄行を非表示にする 3 2022/10/21 22:49
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- その他(動画サービス) https://otologic.jp/free/se/game-fighting01.html h 2 2022/07/28 17:18
- 雑誌・週刊誌 12月22日頃880円で発売する予定の絶世ワールドクラスvol.9を絶対に手に入れる方法を教えてくだ 1 2022/11/25 16:46
- MySQL UPDATE my_items SET item_name '赤い,甘い,ケーキ' WHERE id 1 2023/01/03 09:52
- XML XML同じ名前の要素を自動で集約するツール 1 2022/04/11 09:21
- Visual Basic(VBA) VBA初心者です 検索した数字の行に色をつける 5 2023/02/13 14:22
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perlをwindows環境でshift-jis...
-
[Perl]Shift-JISのXMLを解析する場
-
VBAでCSVファイルを途中行まで...
-
バッチファイルの作り方(CSV→...
-
close()で例外が投げられる理由
-
batファイルでrenameができませ...
-
VBAでCSVファイルの特定行を書...
-
openした後、closeしないでプロ...
-
VBAコードを張り付け後のエクセ...
-
ListBoxのデータを高速でファイ...
-
JavaでCSVファイルを高速に読む...
-
至急お願いします。C言語で.img...
-
タブの色を変更する方法
-
vba dir の相対パス
-
while(<ハンドラ>) {} で行数を...
-
RSS自動生成で文字化け
-
awkスクリプトでダブルクォーテ...
-
unixでのファイルロックの方法...
-
Perlで空白行を削除
-
教えて!perlから.exeファイル...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Perl cgiの文字化けを直したい ...
-
HTTP::Request::Common qw(POST...
-
utf-8のCSVをshift_jisに変換し...
-
ファイル出力をUTF8Nではなくて...
-
[Perl]Shift-JISのXMLを解析する場
-
perlのmysqlで文字化けをする、...
-
文字を一文字ずつ区切りたい
-
perlでuse utf8でsjisのファイ...
-
Perl utf8上でshiftjisをデコード
-
does not map to shiftjis は解...
-
DBIモジュールと Perl5.8
-
消費税の計算で 税込価格から...
-
Data::Dumper;でダンプ後表示し...
-
Perl UTF8で出力
-
perlをwindows環境でshift-jis...
-
バッチファイルの作り方(CSV→...
-
awkスクリプトでダブルクォーテ...
-
VBAでCSVファイルの特定行を書...
-
DOSコマンドで、標準出力を出力...
-
ExcelをCSV書き出す場合のシー...
おすすめ情報