(何の定義も与えられていない場合)
- < → <
- > → >
- & → &
- ' → '
- " → "
- RSSを配信しているのが自分ではない
- 何らかの処理のために無理矢理読み込んでパースしたい
本来であれば、パース処理の方に手を加えるべきなのでしょうが、面倒なので次のような過程を踏んでみました。
手順
- HTTP_Clientなどでファイルの内容を読み込む
- 不正な部分を変換する
- XML文字列として読み込む(simple_load_string)
1. HTTP_Clientなどでファイルの内容を読み込む
たまたまHTTP_Clientを使いましたが、HTTP_Requestでもfile_get_contentsでも何でも良いです。コード例:
require_once 'HTTP/Client.php';
$client = new HTTP_Client();
$client->get('http://movapic.com/feed/user/nobodyplace');
$result = $client->currentResponse();
ちなみに上で読み込んでいるのは「携帯百景」のRSSですね。よくこの問題が起きるので。
2. 不正な部分を変換する
ここが面倒くさい。まぁしかし何とかして読み込めればいいので…次のような作戦を立てました。
- 実体参照に含まれる&と;を数値参照に変換する
- ただし、<、>、&、'、"は除く
コード例:
$str = preg_replace_callback('/(&[^;]+;)/'
, create_function('$matches', 'return mb_encode_numericentity($matches[1], array(0x0000, 0xffff, 0, 0xffff));')
, $result['body'])
;
本当のことを言うとこれは完全な解決ではありません。
上の処理はこういうことをしているんですが、
- × → ×
- × (→ ×)→ ×
3. XML文字列として読み込む(simple_load_string)
というわけで話が前後しますが、読み込み。コード例:
$xml = simplexml_load_string($str);
後は煮るなり焼くなり。
結論
何で上手く言ってるのかよくわかんないけど、結果オーライ!なんでだろ?
オマケ
考えてみれば自分で何回もRSSを出力してきましたけど…この辺のことをルーズにしてることが自分でもあるかも。あんまり自信ない。手抜きでよければ、<![CDATA[ ]]>を使えば良いんですけどね(何でもかんでもそれで良いのかはわかんない)。XMLに実体参照が含まれてパースエラーになってしまう件。