English Japanese Kawa.netxp [Perl] XML::FeedPP - RSS・RDF・Atomフィードの解析・生成・変換・結合

XML::FeedPP モジュールは、 RSS 2.0、RSS 1.0 (RDF)、Atom 0.3(および1.0)フィードの XML ファイルを解析・生成・変換・結合するための Perl モジュールです。
RSS ベースの1種類の共通 API で RSS・RDF・Atom の各フォーマットの処理に対応しているため、 手軽に扱えます。
フィードの読み出し・書き込みはもちろん、 RSSからRDFへ、RDFからAtomへといった各フォーマット間の相互変換も可能です。
他サイトからダウンロードした複数のファイルを結合して、 まとめて1つのファイルとして出力することもできます。

公開版アーカイブ: XML-FeedPP-0.43.tar.gz TARGZ CPAN  ←通常パッケージ

最新版ソースファイル: lib/XML/FeedPP.pm PM

Subversion レポジトリ: http://xml-treepp.googlecode.com/svn/trunk/XML-FeedPP/ SVN

※ XML::FeedPP バージョン 0.30 から、Atom 1.0 に対応しました。(デフォルトは Atom 0.3 です)

サンプルプログラム

Webサーバ上のRSSファイルを受信して、内容を表示する例:

    my $source = 'http://use.perl.org/index.rss';
    my $feed = XML::FeedPP->new( $source );
    print "Title: ", $feed->title(), "\n";
    print "Date: ", $feed->pubDate(), "\n";
    foreach my $item ( $feed->get_item() ) {
        print "URL: ", $item->link(), "\n";
        print "Title: ", $item->title(), "\n";
    }

RDFファイルを生成して、ローカルマシン内に保存する例:

    my $feed = XML::FeedPP::RDF->new();
    $feed->title( "use Perl" );
    $feed->link( "http://use.perl.org/" );
    $feed->pubDate( "Thu, 23 Feb 2006 14:43:43 +0900" );
    my $item = $feed->add_item( "http://search.cpan.org/~kawasaki/XML-TreePP-0.02" );
    $item->title( "Pure Perl implementation for parsing/writing xml file" );
    $item->pubDate( "2006-02-23T14:43:43+09:00" );
    $feed->to_file( "index.rdf" );

RSSファイル・RDFファイルの内容を結合して、Atom 1.0 を生成する例:

    my $feed = XML::FeedPP::Atom::Atom10->new();        # 空の Atom 1.0 フィードを生成
    $feed->merge( "rss.xml" );                          # ローカルのRSSファイルを結合
    $feed->merge( "http://www.kawa.net/index.rdf" );    # Web上のRDFファイルを結合
    my $now = time();
    $feed->pubDate( $now );                             # 更新日時を設定
    my $atom = $feed->to_string();                      # Atom のXMLソースを生成

インストール手順

XML::FeedPP モジュールの利用には XML::TreePPモジュールのみが必要で、 それ以外の外部モジュールには依存しません。

CPAN 経由でインストールできる方は、 CPAN をご利用ください。
CPAN に届いていない最新版を利用したい場合は、 通常通り↓の手順でインストールできます。

$ tar zxvf XML-FeedPP-0.03.tar.gz
$ cd XML-FeedPP-0.03
$ perl Makefile.PL
Writing Makefile for XML-FeedPP
$ make
cp lib/XML/FeedPP.pm blib/lib/XML/FeedPP.pm
Manifying blib/man3/XML::FeedPP.3
$ make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/atom........ok
t/datetime....ok
t/encoding....ok
        1/4 skipped: Encode.pm is required: ISO-8859-1
t/new.........ok
t/rdf.........ok
t/round.......ok
t/rss.........ok
All tests successful, 1 subtest skipped.
Files=7, Tests=170,  1 wallclock secs ( 0.65 cusr +  0.14 csys =  0.79 CPU)
$ sudo make install

XML::FeedPP は Perl 5.005/5.6.x/5.8.x のいずれの環境でも利用できます。 Perl 5.6.x 以下をご利用の場合は、 「Encode.pm is required」としてテストのうち1件がスキップされますが、 動作には影響ありません。 (この場合の制限は、encoding="ISO-8859-1" ファイルの書き出しができないのみ。 encoding="ISO-8859-1" ファイルの読み込みは可能です)

XML::FeedPP/XML::TreePP どちらもコンパイル不要の Pure Perl 実装ですから、 プロバイダのレンタルサーバ環境でも .pm ファイル単体のコピーのみで利用できます。(↓の手順)

.pm ソースファイル単体で利用する場合

プロバイダのレンタルサーバなどで、サーバの管理者権限はないけど オリジナル CGI を設置できる環境などでは、 XML/FeedPP.pm ファイル のみをサーバにコピーするだけでも利用できます。

hogehoge.cgi
XML/FeedPP.pm
XML/TreePP.pm

CGI ファイルと同じ階層に XML ディレクトリを作成して、 その中に FeedPP.pm と TreePP.pm をアップロードしてください。
通常、.pm ファイルのパーミションはデフォルト(644)のままでOKです。
XML ディレクトリのパーミションはデフォルト(755)のままでも構いませんし、 少し厳しく(711)としてもOKです。

仕様

POD の英語は適当なので、こちらの方が分かりやすいです。w

コンストラクタメソッド

以下のような手順で、XML::FeedPP のインスタンスを作成できます。

  $feed = XML::FeedPP->new( 'index.rss' );

サーバ内にある XML ファイルを解析します。
RSS/RDF/Atom フィードの形式は自動的に判定されます。

  $feed = XML::FeedPP->new( 'http://use.perl.org/index.rss' );

WEB サーバ上の XML ファイルをダウンロード〜解析します。
RSS/RDF/Atom フィードの形式は自動的に判定されます。

  $feed = XML::FeedPP->new( '<?xml?><rss version="2.0"><channel>....' );

XML ソースからインスタンスを作成します。
RSS/RDF/Atom フィードの形式は自動的に判定されます。

  $feed = XML::FeedPP::RSS->new();

空の RSS 2.0 インスタンスを作成します。

  $feed = XML::FeedPP::RDF->new();

空の RDF 1.0 インスタンスを作成します。

  $feed = XML::FeedPP::Atom::Atom10->new();

空の Atom 1.0 フィードインスタンスを作成します。

  $feed = XML::FeedPP::RSS->new( link => $link, title => $title, ... );
  $feed = XML::FeedPP::RDF->new( link => $link, description => $desc, ... );
  $feed = XML::FeedPP::Atom->new( link => $link, pubDate => $pubDate, ... );

フィードインスタンスを作成し、続けて チャンネル要素操作系のメソッド を呼び出して、フィードを初期化します。
コンストラクタの引数にキー/値のペアを並べます。(ハッシュを展開した状態)

結合・出力・アイテム追加のメソッド

インスタンスから以下のメソッドが利用できます。

  $feed->load( $source );

現在のインスタンス内の情報を破棄して、指定したフィードを読み込みます。
load() は使わずに、素直に new() メソッドを使ってください。

  $feed->merge( $source );

現在のフィード $feed のチャンネル・アイテム情報に加えて、 指定したフィードの内容を結合します。
第1引数は、new() と同様に読み込み元フィードを指定します。
サイト名や説明文など、もともと登録済みの項目があれば、それは上書きしません。
未記入だった項目は、新しいフィードの内容で登録します。
アイテムについても、未登録の新しいアイテムがあれば、追加します。
(guid でなく)URL ベースでマッチングを行い、 既に存在するアイテムについては、上書きします。

  $feed->to_string( "UTF-8" );

RSS形式またはRDF形式またはAtom形式の XML ソースコードを生成します。(文字列を返す)
第1引数で "Shift_JIS" などの文字コードを指定できますが、"UTF-8" が無難でしょう。

  $feed->to_file( "feed.xml", "UTF-8" );

RSS形式またはRDF形式またはAtom形式の XML ファイルを生成します。
第2引数で "Shift_JIS" などの文字コードを指定できますが、"UTF-8" が無難でしょう。

  $item = $feed->add_item( $url );
  $item = $feed->add_item( $srcitem );

フィードに新しいアイテムを追加して、アイテム要素のインスタンスを返します。
RSS/RDF では <item> 要素、Atom フィードでは <entry> 要素が追加されます。
第1引数には、アイテムの URL を指定します。(第1形式)
または、別のフィードから get_item() メソッド↓で取得したアイテムも指定できます。(第2形式)
URLを含むアイテムの各情報がコピーされます。

  $item = $feed->add_item( link => $link, title => $title, ... );

フィードに新しいアイテムを追加して、続けて アイテム要素操作系のメソッド を呼び出して、アイテムを初期化します。(第3形式)
メソッドの引数にキー/値のペアを並べます。(ハッシュを展開した状態)

  $item = $feed->get_item( $num );          # $num+1 番目のアイテム要素を取り出す
  @list = $feed->get_item();                # 全てのアイテム要素を取り出す

アイテム要素を取り出します。
第1引数を指定した場合は、指定した番号のアイテム要素を取り出します。(最初の要素番号は0)
バージョン 0.19 以降では、負の数を指定して末尾から数えた要素番号を指定できます。(末尾の要素番号が-1)
第1引数を指定しない場合は、全てのアイテムを配列で返します。
普通の配列なので、ループで回して処理したりできます。

  @items = $feed->match_item( link => qr(http://〜), title => qr(Hello〜), ... );

全てのアイテム要素を正規表現で検索し、マッチしたアイテム要素のみを取り出します。
スカラーコンテキストで呼び出した場合は、最初にマッチしたアイテム要素のみを返します。
配列コンテキストで呼び出した場合は、マッチした全てのアイテム要素を返します。
※このメソッドはバージョン0.21以降で対応しています。

  $item = $feed->remove_item( $num );       # $num+1 番目のアイテム要素を削除する
  $item = $feed->remove_item( $url );       # 指定したURLのアイテム要素を削除する

アイテム要素を削除します。
第1引数で、get_item() メソッド↑と同じアイテム番号(最初の要素番号は0)か、 またはアイテムのURLを指定し、削除したアイテムオブジェクトを返します。
バージョン 0.19 以降では、負の数を指定して末尾から数えた要素番号を指定できます。(末尾の要素番号が-1)

  $item = $feed->clear_item();

全てのアイテム要素を一括削除します。
(バージョン 0.12 で追加しました)

  $feed->xmlns( 'xmlns:media' => 'http://search.yahoo.com/mrss' );  # 書き込み
  $url = $feed->xmlns( 'xmlns:itunes' );        # 読み出し
  @list = $feed->xmlns();                       # 一覧

ルート要素で定義するネームスペース(xmlns)を追加または取得します。
第1・第2引数を指定した場合は、ネームスペース/URL の組を登録します。
第1引数のみを指定した場合は、そのネームスペースの現在の値(URL)を返します。
そのネームスペースが未登録の場合は、undef を返します。
引数を指定しない場合は、登録中の全てのネームスペースを配列で返します。

  $feed->sort_item();

アイテムを更新日時(pubDate・dc:data・modified・updated)でソートします。

  $feed->uniq_item();

重複したアイテムを取り除きます。重複は URL で判定します。

  $feed->limit_item( $num );

フィード内のアイテム件数を制限します。
指定値よりも多ければ、それ以降のアイテムを削除します。
負の数を指定すると、リストの末尾から数えて、それ以前のアイテムを削除します。

  $feed->normalize();

フィード内容のノーマライズを行います。
具体的には、更新日時(pubDate・dc:data・modified・updated)フォーマットの正規化を行った上で、 sort_item() メソッドと uniq_item() メソッドを実行します。

チャンネル要素操作系のメソッド

以下のチャンネル要素操作系のメソッドは、XML::FeedPP インスタンスに対して使用します。
RSS・RDF では <channel> 要素、Atom フィードでは <feed> 要素に対する操作になります。

ここにない要素を操作する場合は、 set() get() メソッドを利用してください。

メソッドtitle() RSS<title> RDF<title> Atom 0.3<title> Atom 1.0<title>
  $feed->title( $text );

サイト名を指定します。HTML は利用せずに、テキストのみ利用してください。
引数を指定しない場合は、変更せずに現在の値を返します。

メソッドdescription() RSS<description> RDF<description> Atom 0.3<content> Atom 1.0<content>
  $feed->description( $html );

サイトの説明文を指定します。HTML を利用できます。
引数を指定しない場合は、変更せずに現在の値を返します。

メソッド pubDate() RSS<pubDate> RDF<dc:date> Atom 0.3<modified> Atom 1.0<updated>
  $feed->pubDate( $date );

サイトの更新日時を指定します。 指定値には、3種類のフォーマットが利用可能です。
RSS/RDF/Atom のネイティブフォーマットに加えて、 Perl の time() 関数で得られる秒数も指定できます。
引数を指定しない場合は、作成日時を W3CDTF フォーマットで返します。

メソッドcopyright() RSS<copyright> RDF<dc:rights> Atom 0.3<copyright> Atom 1.0<rights>
  $feed->copyright( $text );

サイトの制作者・権利者名を指定します。
引数を指定しない場合は、変更せずに現在の値を返します。

メソッドlink() RSS<link> RDF<link> Atom<link> Atom<link>
  $feed->link( $url );

サイトのトップページURLを指定します。
引数を指定しない場合は、変更せずに現在の値を返します。

メソッドlanguage() RSS<language> RDF<dc:language> Atom 0.3/1.0<feed xml:lang="">
  $feed->language( $lang );

サイトの言語を指定します。
引数を指定しない場合は、変更せずに現在の値を返します。

メソッドimage() RSS<image> RDF<image> Atom 0.3<link> Atom 1.0<link>
  $feed->image( $url, $title, $link, $description, $width, $height )

RSS リーダー等に表示する画像を指定します。
引数を指定しない場合は、変更せずに現在の値を同じ順の配列で返します。
(バージョン 0.12 では Atom にも対応しました。rel="icon"を使用します)

アイテム要素操作系のメソッド

以下のアイテム要素操作系のメソッドは、add_item() または get_item() メソッドで 取得したインスタンスに対して使用できます。
RSS/RDF では <item> 要素、Atom フィードでは <entry> 要素に対する操作になります。

ここにない要素を操作する場合は、 set() get() メソッドを利用してください。

メソッドtitle() RSS<title> RDF<title> Atom 0.3<title> Atom 1.0<title>
  $item->title( $text );

アイテムの件名を指定します。HTML は利用せずに、テキストのみ利用してください。
引数を指定しない場合は、変更せずに現在の値を返します。

メソッドdescription() RSS<description> RDF<description> Atom 0.3<content> Atom 1.0<content>
  $item->description( $text );

アイテムの説明文を指定します。HTML を利用できます。
引数を指定しない場合は、変更せずに現在の値を返します。

メソッド pubDate() RSS<pubDate> RDF<dc:date> Atom 0.3<modified> Atom 1.0<updated>
  $item->pubDate( $text );

アイテムの作成日時を指定します。 指定値には、3種類のフォーマットが利用可能です。
RSS/RDF/Atom のネイティブフォーマットに加えて、 Perl の time() 関数で得られる秒数も指定できます。
引数を指定しない場合は、作成日時を W3CDTF フォーマットで返します。

メソッド category() RSS<category> RDF<dc:subject> Atom 0.3(非対応) RDF 1.0<category>
  $item->category( $text );

アイテムの分類名(ジャンル)を指定します。
引数を指定しない場合は、変更せずに現在の値を返します。
※現状では、複数の分類名は指定できません。 (→複数の分類名に対応しました。2006/04/30)

メソッドauthor() RSS<author> RDF<creator> Atom 0.3/1.0<author><name>
  $item->author( $text );

アイテムの著者名を指定します。
引数を指定しない場合は、変更せずに現在の値を返します。

メソッドguid() RSS<guid> RDF(非対応) Atom 0.3<id> Atom 1.0<id>
  $item->guid( $text );      # 書き込み
  $text = $item->guid();     # 読み出し

アイテムのIDを指定します。
引数を指定しない場合は、変更せずに現在の値を返します。

メソッド link() RSS<link> RDF<link> Atom 0.3<link> Atom 1.0<link>
  $url = $item->link();      # 読み出し

アイテムのURLを返します。(読み出し専用です)

set() get() 汎用メソッド

XML::FeedPP の標準メソッドで処理できる要素は、RSS/RDF/Atom の主な要素に限られます。 その他、<media:*> の media モジュールなどの特殊な要素を処理する場合には、 set() get() メソッドを利用してください。

  $item->set( 'module:name' => $value );

<item><module:name> アイテムの子要素の値を指定します。

  $item->set( 'module:name@attr' => $value );

<item><module:name attr="$value"> アイテムの子要素の属性値を指定します。

  $item->set( '@attr' => $value );

<item attr="$value"> アイテム自体の属性値を指定します。

  $item->set( '@module:attr' => $value );

<item module:attr="$value"> ネームスペース付の属性値も指定可能です。

  $item->set( 'hoge/pomu@hare' => $value );

<item><hoge><pomu hare="$value"> アイテムの孫要素の属性の値を指定します。

get() メソッドは、set() メソッドの第1引数と同じ形式で 要素名・属性名を指定すると、その値を返します。

これらの get() set() メソッドは非常に強力ですが、 RSS/RDF/Atom の各フォーマット間での要素名の差異を自動では吸収しないため、 出力フォーマットに合わせて注意しながら利用する必要があります。

また、モジュールを追加する場合は、xmlns() メソッドで フィードにネームスペースを登録しておく必要があります。

日付フォーマット

pubDate() メソッドの入力値として、 下記の3種類の日付フォーマットが利用できます。

    pubDate( "Thu, 23 Feb 2006 14:43:43 +0900" );

HTTP プロトコルの日時フォーマットです。 RSS 2.0 のネイティブ形式になります。
RSS 2.0 インスタンス内部格納時や、XMLコード出力時もこの形式です。

    pubDate( "2006-02-23T14:43:43+09:00" );

W3CDTF の日時フォーマットです。 RDF/Atom のネイティブ形式になります。
なお、pubDate() メソッドの出力値(引数なし時)は、 どのフォーマットでも常にこの W3CDTF フォーマットとなります。
RSS 2.0 の場合も、W3CDTF フォーマットに変換してから出力されます。
タイムゾーンが揃っていれば、ソートしやすいのが特徴です。

    pubDate( 1140705823 );          # 2006/02/23 05:43:43 GMTを指定する
    pubDate( time );                # 現在の時刻を指定する(GMT)

1970年1月1日からの秒数です。Perl の time() 関数の値です。
pubDate() メソッドへの入力値として利用できます。
フィード内に記述されるタイムゾーンは、GMT 扱いになります。
バージョン0.08からは、サーバ時計のタイムゾーンが適用されるようになりました。

media モジュールの利用

set() メソッドは複数の要素・属性を同時に更新することができます。
<media:*> の media モジュールは、set() メソッドを利用して指定します。

    my $item = $feed->add_item( 'http://www.kawa.net/' );
    my $media = {
        'media:title'           =>   'Kawa.net xp',
        'media:text'            =>   'Welcome to Kawa.net xp',
        'media:text@type'       =>   'text',
        'media:thumbnail@url'   =>   'http://www.kawa.net/xp/images/xp-title-256.gif',
        'media:thumbnail@width' =>   256,
        'media:thumbnail@height' =>  48,
        'media:content@url'     =>   'http://www.kawa.net/xp/images/xp-title-512.gif',
        'media:content@type'    =>   'image/gif',
        'media:content@width'   =>   512,
        'media:content@height'  =>   96,
    };
    $item->set( %$media );

以下のような XML コードが生成されます。

    <item>
        <link>http://www.kawa.net/</link>
        <media:title>Kawa.net xp</media:title>
        <media:text type="text">Welcome to Kawa.net xp</media:text>
        <media:content type="image/gif" height="96" width="512"
            url="http://www.kawa.net/xp/images/xp-title-512.gif" />
        <media:thumbnail height="48" width="256"
            url="http://www.kawa.net/xp/images/xp-title-256.gif" />
    </item>

ポッドキャスト・ビデオポッド

ポッドキャスティング・ビデオポット用の RSS ファイルは 以下の手順で作成できます。

    my $feed = XML::FeedPP::RSS->new();
    $feed->link( 'http://example.com/' );
    $feed->title( "Yusuke Kawasaki's podcasting!" );
    $feed->xmlns( 'xmlns:itunes' => 'http://www.itunes.com/DTDs/Podcast-1.0.dtd' );
    my $itunes = {
        'itunes:author'     =>  'Yusuke Kawasaki',
        'itunes:image@href' =>  'http://example.com/image.jpg',
        'itunes:category@text'                  =>  '2nd level',
        'itunes:category/itunes:category@text'  =>  '3rd level',
    };
    $feed->set( %$itunes );
    my $item1 = $feed->add_item( 'http://example.com/blog/2006/0227/' );
    $item1->title( "2006/02/27 podcasting" );
    my $podcast = {
        'enclosure@url'     =>  'http://example.com/blog/2006/0227/audio.mp3',
        'enclosure@length'  =>  1048576,
        'enclosure@type'    =>  'audio/mpeg',
    };
    $item1->set( %$podcast );
    my $item2 = $feed->add_item( 'http://example.com/blog/2006/0228/' );
    $item2->title( "2006/02/27 video podcast" );
    my $videopod = {
        'enclosure@url'     =>  'http://example.com/blog/2006/0228/video.m4v',
        'enclosure@length'  =>  5242880,
        'enclosure@type'    =>  'video/quicktime',
    };
    $item2->set( %$videopod );

以下のような RSS ファイルが生成されます。

    <?xml version="1.0" encoding="UTF-8" ?>
    <rss version="2.0" xmlns:itunes="http://www.itunes.com/DTDs/Podcast-1.0.dtd">
    <channel>
        <itunes:author>Yusuke Kawasaki</itunes:author>
        <itunes:category text="2nd level">
            <itunes:category text="3rd level" />
        </itunes:category>
        <itunes:image href="http://example.com/image.jpg" />
        <link>http://example.com/</link>
        <title>Yusuke Kawasaki's podcasting!</title>
        <item>
            <enclosure length="1048576" type="audio/mpeg"
                url="http://example.com/blog/2006/0227/audio.mp3" />
            <link>http://example.com/blog/2006/0227/</link>
        </item>
        <item>
            <enclosure length="5242880" type="video/quicktime"
                url="http://example.com/blog/2006/0228/video.m4v" />
            <link>http://example.com/blog/2006/0228/</link>
        </item>
    </channel>
    </rss>

でも、iPod の実機では動作確認してません。動かなかったらゴメンナサイ。

更新履歴

コメントはこちらへ by AjaxCom

その他のページへのリンク

Kawa.netxp © Copyright 2006-2011 Yusuke Kawasaki