プロが教える店舗&オフィスのセキュリティ対策術

RSSからデータ取り出しについて、ご教授ください。

use XML::RSS;

をperlに実装して、RSSファイルを分解し、必要なデータだけ取り出すスクリプトを使用しています。

データがとれなくなったので、ソースを調べたところ、配布元が改造をしたらしく

<rss version="2.0">
<channel>
<title>RSSによる順位公開</title>
<item>
<title>タイトル1</title>
<rank>1</rank>
<preranks>
<rank>3</rank>
</preranks>
</item>
<item>
<title>タイトル2</title>
<rank>2</rank>
<preranks>
<rank>10</rank>
</preranks>
</item>


のようになっていました。
<rank> はそのときのタイトルの表示ランキングで、<preranks>は、RSSが更新される以前の表示ランキングを示しています。
ちなみに、preranks からネストしている rank を別の表記にしたり、ネストしない構造に変更することは、対応できないとの回答でした。

$rss->parse( RSSのURL );

for (@{$rss->{'items'}}) {
$el00 = $_->{title};
$el01 = $_->{rank};
}

と実行すると、$el00は、タイトル1 や タイトル2 と希望通りの形に分解できるのですが、$el01 は 13 や 210 など、<preranks> の内側の <rank> と並べた数字で表示されてしまいます。

といって、 $el01 = $_->{preranks}; でも数字がとれません。

こうした構造のRSSで、<rank> と <preranks> をデータとして分解するには、どんな記述をしたらいいのでしょうか?

よろしくご教授お願いします。

A 回答 (1件)

XML::RSSモジュールを使って試してみましたが、パースがうまくいかないですね。


XML::RSSモジュールにこだわらなくていいのなら、XML::XPathモジュールを使えば、下記のようなスクリプトでパースができると思います。

#!/usr/bin/env perl
use v5.16;
use warnings;
use utf8;
use open IO => qw/:utf8 :std/;
use autodie;
use XML::XPath;

my $string = << 'EOF';
<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
<channel>
<title>RSSによる順位公開</title>
<item>
<title>タイトル1</title>
<rank>1</rank>
<preranks>
<rank>3</rank>
</preranks>
</item>
<item>
<title>タイトル2</title>
<rank>2</rank>
<preranks>
<rank>10</rank>
</preranks>
</item>
</channel>
</rss>
EOF

my $xpath = XML::XPath->new(xml => $string);
for my $item ($xpath->findnodes('//item'))
{
say 'タイトル:', $item->findvalue('title');
say '新ランク:', $item->findvalue('rank');
say '旧ランク:', $item->findvalue('preranks/rank');
}


実行結果は下記のとおりとなります。

タイトル:タイトル1
新ランク:1
旧ランク:3
タイトル:タイトル2
新ランク:2
旧ランク:10


XPathは一度覚えちゃえば、いろいろな場面で活用できます。
表示させたいところを細かく指定できるのが便利です。
    • good
    • 0

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