徒然なるままに プログラミングメモや日々の生活などつれづれとつづっていくblog

2013年7月7日

RSSリーダーを作ってみる その2

Filed under: PHP,アンテナサイト,ソース配布 — ranpei @ 1:38 AM

前回の公開したrssLoader
実はRSS2.0だとitemタグを解析できないというバグがある

どこが悪くて読み込めないかというと以下の部分
[php]
// 各記事を取得する
foreach($rssDom->item as $item) {

$itemBean = new itemBean();
[/php]
RSSのフォーマット・仕様・構造 – RSS1.0、RSS2.0、Content-Type」を見ていただくと分かるが
RSS1.0ではitemタグはchannelタグと同列のDom階層に存在するが
RSS2.0ではitemタグはchannelタグ配下のDom階層にある

RSS2.0を読み込むには「$rssDom->channel->item」としなければならないのだ

修正したソースは以下のようになる
[php]
<?php
require_once __DIR__."/channelBean.php";
require_once __DIR__."/itemBean.php";
require_once __DIR__."/rssException.php";
require_once __DIR__."/lib/httpConnecter.php";
require_once __DIR__."/lib/xmlLoader.php";

class rssLoader {

const VERSION_1 = 1;
const VERSION_2 = 2;

const VERSION_ALL = 0;

public function __construct() {
}

public function __destruct() {
}

/**
* RSSを読み込みchannelBeanで取得
*
* @param int $version 対象RSSバージョン指定
* 全バージョンのRSS : rssLoader::VERSION_ALL
* バージョン1.0のRSS : rssLoader::VERSION_1
* バージョン2.0のRSS : rssLoader::VERSION_2
*
*/
public function loadRss($path, $version = self::VERSION_ALL) {

/**
* RSSを取得
*/
$http = new httpConnecter();
$http->connect($path);
$rssStr = $http->loadText();
if($rssStr === "") {

// 取得できなければエラー
throw rssException::notRss("RSSファイルの取得ができませんでした。");
}

/**
* RSSを解析
*/
$xml = new xmlLoader();
$rssDom = $xml->parsor($rssStr);

// すべてのバージョン
if($version == self::VERSION_ALL) {

try {

return $this->loadRss2($rssDom);

} catch (Exception $e) {

return $this->loadRss1($rssDom);
}
}

// rss1.0
else if(isset($rssDom->attributes()->version) == false && $version == self::VERSION_1) {

return $this->loadRss1($rssDom);
}
// rss2.0
else if($rssDom->attributes()->version == 2 && $version == self::VERSION_2) {

return $this->loadRss2($rssDom);
}
else {

throw rssException::notMatchVersion("このRSSは正しい型式ではありません。");
}

return $channelBean;
}

/**
* RSS1.0を解析
* @param unknown $rssDom
*/
private function loadRss1($rssDom) {

//if($rssDom->attributes()->version != self::VERSION_1) {

// throw rssException::notMatchVersion("このRSSはVertion1.0ではありません。");
//}

$channelBean = new channelBean();

$channelBean->encoding = "UTF-8";
$channelBean->rssVersion = self::VERSION_1;
$channelBean->rssUrl = $rssDom->channel->link;

// RSSの本体情報を取得
if(isset($rssDom->channel->title)) {
$channelBean->title = $rssDom->channel->title;
}
if(isset($rssDom->channel->link)) {
$channelBean->link = $rssDom->channel->link;
}
if(isset($rssDom->channel->description)) {
$channelBean->description = $rssDom->channel->description;
}
// dcの要素を取得
$dc = $rssDom->channel->children(‘http://purl.org/dc/elements/1.1/’);
if(isset($dc->date)) {
$channelBean->date = $dc->date;
}
if(isset($dc->language)) {
$channelBean->language = $dc->language;
}
if(isset($dc->creator)) {
$channelBean->creator = $dc->creator;
}

// ver1.0各記事を取得する
foreach($rssDom->item as $item) {

$itemBean = new itemBean();

if(isset($item->title)) {
$itemBean->title = $item->title;
}
if(isset($item->link)) {
$itemBean->link = $item->link;
}
if(isset($item->description)) {
$itemBean->description = $item->description;
}
if(isset($item->category)) {
$itemBean->category = $item->category;
}
if(isset($item->pubDate)) {
$itemBean->date = $item->date;
}
// dcの要素を取得
$dc = $item->children(‘http://purl.org/dc/elements/1.1/’);
if(isset($dc->date)) {
$itemBean->date = $dc->date;
}
if(isset($dc->subject)) {
$itemBean->category = $dc->subject;
}
if(isset($dc->creator)) {
$itemBean->creator = $dc->creator;
}

array_push($channelBean->itemList, $itemBean);
}

return $channelBean;
}

/**
* RSS2.0を解析
* @param unknown $rssDom
*/
private function loadRss2($rssDom) {

if($rssDom->attributes()->version != self::VERSION_2) {

throw rssException::notMatchVersion("このRSSはVertion2.0ではありません。");
}

$channelBean = new channelBean();

$channelBean->encoding = "UTF-8";
$channelBean->rssVersion = self::VERSION_2;
$channelBean->rssUrl = $rssDom->channel->link;

// RSSの本体情報を取得
if(isset($rssDom->channel->title)) {
$channelBean->title = $rssDom->channel->title;
}
if(isset($rssDom->channel->link)) {
$channelBean->link = $rssDom->channel->link;
}
if(isset($rssDom->channel->description)) {
$channelBean->description = $rssDom->channel->description;
}
// dcの要素を取得
$dc = $rssDom->channel->children(‘http://purl.org/dc/elements/1.1/’);
if(isset($dc->date)) {
$channelBean->date = $dc->date;
}
if(isset($dc->language)) {
$channelBean->language = $dc->language;
}
if(isset($dc->creator)) {
$channelBean->creator = $dc->creator;
}

// ver2.0各記事を取得する
foreach($rssDom->channel->item as $item) {

$itemBean = new itemBean();

if(isset($item->title)) {
$itemBean->title = $item->title;
}
if(isset($item->link)) {
$itemBean->link = $item->link;
}
if(isset($item->description)) {
$itemBean->description = $item->description;
}
if(isset($item->category)) {
$itemBean->category = $item->category;
}
if(isset($item->pubDate)) {
$itemBean->date = $item->date;
}
// dcの要素を取得
$dc = $item->children(‘http://purl.org/dc/elements/1.1/’);
if(isset($dc->date)) {
$itemBean->date = $dc->date;
}
if(isset($dc->subject)) {
$itemBean->category = $dc->subject;
}
if(isset($dc->creator)) {
$itemBean->creator = $dc->creator;
}

array_push($channelBean->itemList, $itemBean);
}

return $channelBean;
}
}
[/php]
上記ソースはほかにもネームスペース「dc」の要素が読み込めていない問題などを修正している

ダウンロードはこちらから→[download id=”1″]

コメントはまだありません »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress