現在、PHP の simplexml_load_string で、RSSファイルを読み込ませて、
解析するプログラムを作っています。一部、読み込めないRSSがあり、
>Uncaught exception Exception: simplexml_load_string(): Entity: line 1: parser error :
>Start tag expected, '<' not found
というエラーが出ています。このエラーを判る方法(キャッチする)を教えて下さい。
または、file_get_contents したXML形式のstringを、XML形式なのか?そうでないのか? が
判る方法を教えて下さい。
例外を出さないんだそうです。
他パースエラーが発生した場合の原因がわからない
上記の制御文字コードをエラーとして試しに出力しようとしたら、
PHPでのXMLパースエラー出力は必須だね - 今からお前んちこいよ
try catchで例外としてキャッチできなかった。
どうやら warning エラー。
参考:php - How do I handle Warning: SimpleXMLElement::__construct()? - Stack Overflow
set_error_handler を使う。
エラーハンドラで例外を投げるようにすると、今 書いているであろうコードがそのまま使えそうです。
php のマニュアルには、こんなことが書いてあります。
エラー / 例外 ¶
XML データ内でエラーが見つかるたびに E_WARNING エラーメッセージが発生します。
ヒント libxml_use_internal_errors() ですべての XML エラーを抑制し、 後から libxml_get_errors() で取得することもできます。
PHP: simplexml_load_string - Manual
「ヒント」の部分について、具体的なコードは、マニュアルの libxml_get_errors() に記載があります。
または、file_get_contents したXML形式のstringを、XML形式なのか?そうでないのか? が
判る方法を教えて下さい。
あくまでも簡易的な方法ですけど、先頭が XML宣言になっているかどうかで判断できます。
先頭の 5byte が "<?xml" かどうかで判定します。
# XML のはずなんだけど、タグが崩れてる、とかには使えませんが。
エラーを判別する方法は、libxml_use_internal_errors を呼んでから libxml_get_errors で取得した配列が空か否かを確認する、ということになるでしょうか。
エラー自体を回避するには、
1. HTTP レスポンスの Content-Type から符号化方式を判別する
2. mb_convert_encoding で特定した符号化方式から UTF-8 にレスポンスを変換する(HTTP の仕様上、レスポンスに UTF-16 を使用する場合 Network Byte Order を使用しなければならないらしいので、UTF-16BE から UTF-8 に変換することになります。)
3. 変換後のレスポンスに対して simplexml_load_string を呼ぶ
という手順はどうでしょう。この場合、HTTP レスポンスの header を知る必要があるため file_get_contents で XML を取得することはできません。別途ライブラリか curl extension を使う必要があります。
オーバーヘッドがあるようですがエラー制御演算子を使って無視する方法はどうでしょう。