XML::RSS::Parserを使っているとXML::SAX::PurePerlがコケる

単純にサンプルのソースみたら簡単そうだったので、XML::RSS::Parserを使ってみたのですが、ある程度の量のRSSをさばいていたら

utf8 "hogehoge" does not map to Unicode at /usr/local/share/perl/5.10.1/XML/SAX/PurePerl/Reader/Stream.pm line 37.

と言うエラーを吐き出しはじめて、そのうち停止してしまう・・。

XML::SAX::PurePerlと言う部分が悪そうなので検索してみると以下のような記事が。

[perl] ある日 XML::Simple がいきなりこけて泣かないために
http://d.hatena.ne.jp/sfujiwara/20090730/1248959524

モジュールのインストールの順番によってデフォルトのパーサーが変わってしまうとのこと。
かなり前にnaoya氏のブログで見かけたようなネタだ!

XML::Simpleのようにパーサーを指定すればいいのだとわかったわけだけども、XML::RSS::Parserでのパーサーの指定方法がわからない・・。

XML::RSS::ParserのDEPENDENCIESを見ると、XML::SAXが使われているそうなのでこちらを見たら指定方法が書いてあった!

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Encode;
use XML::SAX;
use Data::Dumper;

# get a list of known parsers
my $parsers = XML::SAX->parsers();

warn Dumper $parsers;

実行してみると、やはりXML::SAX::PurePerlが指定されていた。

$VAR1 = [
          {
            'Features' => {
                            'http://xml.org/sax/features/namespaces' => '1'
                          },
            'Name' => 'XML::SAX::PurePerl'
          }
        ];

パーサーにXML::LibXML::SAXを設定してみる。

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Encode;
use XML::SAX;
use Data::Dumper;

# get a list of known parsers
my $parsers = XML::SAX->parsers();

# update a parser
XML::SAX->add_parser(q(XML::LibXML::SAX));

warn Dumper $parsers;

# save parsers
XML::SAX->save_parsers();

パーサーにXML::LibXML::SAXが追加されたことまでは確認できたものの、保存してみようとしたところ権限がないと言うエラーがでてしまった。

$VAR1 = [
          {
            'Features' => {
                            'http://xml.org/sax/features/namespaces' => '1'
                          },
            'Name' => 'XML::SAX::PurePerl'
          },
          {
            'Features' => {
                            'http://xml.org/sax/features/namespaces' => 1
                          },
            'Name' => 'XML::LibXML::SAX'
          }
        ];
Cannot write to /usr/local/share/perl/5.10.1/XML/SAX/ParserDetails.ini: Permission denied at /usr/local/share/perl/5.10.1/XML/SAX.pm line 191.

パーサーの指定をファイルに保存せずにつど指定するか、rootになってParserDetails.iniを書き換えるかすれば解決です。

perl -MXML::SAX -e "XML::SAX->add_parser(q(XML::LibXML::SAX))->save_parsers()"
http://perl-xml.sourceforge.net/faq/#parserdetails.ini

ちなみにDebian環境なので、他のOSやperlbrewとかの環境の場合は適宜パスを読み替えてください。

よくよく確認してみると、oreilly.comで買ったPerl & XMLのChapter 5:SAXに書かれていました・・。