RSSフィードを扱う際、XML系関数を利用したライブラリで解析するよりも、preg_match などで必要な部分だけを切り出す「スクレイピング処理」をした方が幸せになれそうです。PHPのXML系関数はどうにも。。
まず準備として、タグで囲まれた中身を切り出すための簡単な関数を用意しておきます。文字コードはUTF-8が前提です。

//1つだけ切り出す
function clip($str,$tag_name)
{
   preg_match("/<$tag_name.*?>(.+?)<\/$tag_name>/isu",$str,$matches);
   if(isset($matches[1]))	return $matches[1];
   else				return NULL;
}
//全て切り出す
function clipall($str,$tag_name)
{
   preg_match_all("/<$tag_name.*?>(.+?)<\/$tag_name>/isu",$str,$matches);
   if(isset($matches[1]))	return $matches[1];
   else				return NULL;
}
上の二つの関数は、文字列$strから$tag_nameタグで囲まれた部分を切り出します。

ではRSSフィードを読み込みます。たまに EUC-JP や Shift_JIS で出力している サービスも見かけますので、文字コードを変換しておきます。
$rss = @file_get_contents("http://***************/index.rdf");
if(!$rss)   die("cannnot get rss file");
$rss = mb_convert_encoding($rss,'UTF-8','auto');
次にチャンネル情報です。RSS1.0とRSS2.0では必ず、itemタグ以前にチャンネル情報が書かれていますので、その部分を mbsplit で切り出します。
$channel = array();
$split_rss = mbsplit("<item.*?>",$rss,2);
if(count($split_rss)==2)
{
   $ch = $split_rss[0];//チャンネル情報を含む部分
   $channel['title'] = clip($ch,"title");
   $channel['link'] = clip($ch,"link");
   $channel['description'] = clip($ch,"description");
   $date = clip($ch,"dc:date");//RSS1.0
   if(!$date)	$date = clip($ch,"pubDate");//RSS2.0
   if($date)	$channel['date'] = date("Y-m-d H:i:s",strtotime($date));
   else		$channel['date'] = NULL;
}
最後にエントリーリストです。itemタグで囲まれた部分を全て切り出します。
$entry_list = array();
$items = clipall($rss,"item");
if($items)
{
   foreach($items as $item)
   {
      $entry = array();
      $entry['title'] = clip($item,"title");
      $entry['link'] = clip($item,"link");
      $entry['description'] = clip($item,"description");
      $date = clip($item,"dc:date");//RSS1.0
      if(!$date)	$date = clip($item,"pubDate");//RSS2.0
      if($date)		$entry['date'] = date("Y-m-d H:i:s",strtotime($date));
      else		$entry['date'] = NULL;
      $entry_list[] = $entry;
   }
}
あとは、必要に応じてタグやtrimやらの処理を加えてやればなかなか使えるものになります。とりあえず結果を出力。
print_r($channel);
print_r($entry_list);
こんなのでいいのか?と言われそうな何とも頼りないコードですが、PEARのXML_Feed_Parser や XML_RSS なんかでXMLエラーになるRSSファイルでも、問題なく読み込んでくれます。
2008年06月17日01時17分41秒
カテゴリ: スクレイピング