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の直後です。
引用元:Githubイシューのコメントより
else {
$data = $this->raw_data;
}
//ここ
$data = SimplePie_Misc::stripInvalidXml($data);
早速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にデータをフェッチする)
ということはこの下に追記すれば・・
~完~
この記事はお役に立てましたか?
いいえ
ヤフーに戻ります