web-dev-qa-db-ja.com

SimpleXMLを使用してRSSフィードを読み取る

PHPとsimpleXMLを使用して、次のRSSフィードを読み取ります。

http://feeds.bbci.co.uk/news/england/rss.xml

必要な情報のほとんどは次のように取得できます。

$rss = simplexml_load_file('http://feeds.bbci.co.uk/news/england/rss.xml');

echo '<h1>'. $rss->channel->title . '</h1>';

foreach ($rss->channel->item as $item) {
   echo '<h2><a href="'. $item->link .'">' . $item->title . "</a></h2>";
   echo "<p>" . $item->pubDate . "</p>";
   echo "<p>" . $item->description . "</p>";
} 

しかし、次のタグにあるサムネイル画像をどのように出力しますか:

<media:thumbnail width="66" height="49" url="http://news.bbcimg.co.uk/media/images/51078000/jpg/_51078953_226alanpotbury.jpg"/>  
20
geoffs3310

SimpleXMLは、名前空間の処理がかなり悪いです。 2つの選択肢があります。最も単純なハックは、フィードのコンテンツを文字列に読み取り、名前空間を置き換えることです。

_$feed = file_get_contents('http://feeds.bbci.co.uk/news/england/rss.xml');
$feed = str_replace('<media:', '<', $feed);

$rss = simplexml_load_string($feed);
...
_

これで、要素thumbnailに直接アクセスできます。

よりエレガントな(実際にはではない)メソッドは、名前空間が使用するURIを見つけることです。 http://feeds.bbci.co.uk/news/england/rss.xml のソースコードを見ると、それは_http://search.yahoo.com/mrss/_を指していることがわかります。

これで、SimpleXMLElementのchildren()メソッドでこのURIを使用して、media:thumbnail要素のコンテンツを取得できます。

_$rss = simplexml_load_file('http://feeds.bbci.co.uk/news/england/rss.xml');

foreach ($rss->channel->item as $item) {
    $media = $item->children('http://search.yahoo.com/mrss/');
    ...
}
_
5
Björn

すでにご存じのとおり、SimpleXMLでは、オブジェクトプロパティ演算子_->_を使用してノードの子を選択するか、配列アクセス_['name']_を使用してノードの属性を選択できます。それは素晴らしいですが、操作は、選択したものが属している場合にのみ機能します同じ名前空間に

名前空間から別の名前空間に "ホップ"したい場合は、 children() または attributes() メソッド。あなたの場合、グローバル名前空間に_<item/>_があり、探しているノードが「メディア」名前空間*にあり、属性が再びグローバル名前空間にあるため、これは少しトリッキーになります(それらはプレフィックスは付いていません。)通常のオブジェクト/配列表記を使用すると、 "hop"を2回実行する必要があります。

_foreach ($rss->channel->item as $item)
{
    // we load the attributes into $thumbAttr
    // you can either use the namespace prefix
    $thumbAttr = $item->children('media', true)->thumbnail->attributes();

    // or preferably the namespace name, read note below for an explanation
    $thumbAttr = $item->children('http://search.yahoo.com/mrss/')->thumbnail->attributes();

    echo $thumbAttr['url'];
}
_

*注意

名前空間を「メディア」名前空間と呼んでいますが、それは実際には正しくありません。名前空間の名前は_http://search.yahoo.com/mrss/_であり、 "media"は単なる接頭辞です。覚えておくべき重要なことは、_http://search.yahoo.com/mrss/_が名前空間の実際の名前であることです。ある時点で、RSSプロバイダーがプレフィックスをたとえば「yahoo」に変更することを決定する場合があり、スクリプトが「media」プレフィックスを参照している場合、スクリプトは機能しなくなります。ただし、名前空間名を使用すると、プレフィックスに関係なく機能し続けます。

19
Josh Davis