invalid XMLエラーの対処法【SimplePie】

SimplePieでRSSフィードを取得した際、まれに発生するinvalid XMLエラー。これをソースコード側で解決する方法のメモ。v1.5.6以上で動作確認済み。複数フィードにも対応。

結論

SimplePie.phpを開き、init関数内「//Empty response check」コメント行のすぐ上に以下のコードを追加。

$this->raw_data = preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/', ' ', $this->raw_data);

追加例:

if ($this->feed_url !== null)
{
~略~
}

//ここに追加
$this->raw_data = preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/', ' ', $this->raw_data);

//Empty response check
if(empty($this->raw_data)){
~略~
}

このエラーの原因は制御文字が含まれていること。なので正規表現で調べてそれらを半角スペースに置き換える。半角スペースにしている理由は、完全に消すのが何となく恐かったため。てへ

注意点として、SimplePieをバージョンアップする度に追記し直す必要がある。あとご利用は自己責任で。

経緯

まず、以下のようにクラス呼び出し側のソースコード内で対応してみた。

$feed = new SimplePie;
$feed->set_feed_url($feeds);
~略~
$feed->init();
$feed->handle_content_type();
$items = $feed->get_items();
$items = preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/', ' ', $items);

タイミングが遅かったようで失敗。

次にGithubのissueを調べてみた。するとこんなものを見つけた。

呼び出すタイミングについても丁寧にコメントがあった。

データがフェッチされた直後に、SimplePieCoreクラスのinit関数内で関数を呼び出します。elseの直後です。

else {
$data = $this->raw_data;
}

//ここ
$data = SimplePie_Misc::stripInvalidXml($data);

引用元:Githubイシューのコメントより

早速Misc.phpにその関数を追記し、SimplePie.phpの該当箇所を探す。が、見つからない。そこでふと気付く。

あのコメントが10年前のものだった、ということに。

失敗続きだが、ひとまず$this->raw_dataをどうにかすればいいという教訓は得られた。というわけでSimplePie.php内の$this->raw_dataを追うことにした。fetch_data関数内で代入していることが分かったので、そのすぐ下にコードを追記してみた。

$this->raw_data = $file->body;
preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/', ' ', $this->raw_data);

いけると思ったがこれも失敗。でも何となく近づいている気はする。今度はfetch_dataが呼び出されている場所を探した。するとinit関数内にありそこにはこんなコメントが。

//Fetch the data via SimplePie_File into $this->raw_data
(SimplePie_Fileを介して$this>raw_dataにデータをフェッチする)

ということはこの下に追記すれば・・

~完~

この記事は役に立ちましたか?

はい(以下をポチッと)

ブログランキング・にほんブログ村へ

コメントを残す