使用SimpleXML读取RSS提要

geo*_*310 20 php xml rss simplexml

我使用PHP和simpleXML来阅读以下rss feed:

http://feeds.bbci.co.uk/news/england/rss.xml
Run Code Online (Sandbox Code Playgroud)

我可以得到我想要的大部分信息:

$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>";
} 
Run Code Online (Sandbox Code Playgroud)

但是,我如何输出以下标记中的缩略图:

<media:thumbnail width="66" height="49" url="http://news.bbcimg.co.uk/media/images/51078000/jpg/_51078953_226alanpotbury.jpg"/>  
Run Code Online (Sandbox Code Playgroud)

Jos*_*vis 19

如您所知,SimpleXML允许您使用对象属性运算符选择节点的子->节点,或使用数组访问权限选择节点的属性['name'].它很棒,但只有当您选择的属于同一名称空间时,该操作才有效.

如果要从命名空间"跳转"到另一个命名空间,可以使用children()attributes()方法.在您的情况下,这有点棘手,因为您<item/>在全局命名空间中,您正在寻找的节点位于"media"命名空间*中,然后属性再次位于全局命名空间中(它们不是前缀.)所以使用普通的对象/数组表示法,你必须"跳"两次:

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'];
}
Run Code Online (Sandbox Code Playgroud)

*注意

我将命名空间称为"媒体"命名空间,但这并不正确.命名空间名称是http://search.yahoo.com/mrss/,而"media"只是一个前缀,如果你愿意的话是某种别名.请记住,重要的http://search.yahoo.com/mrss/是名称空间的真实名称.在某些时候,您的RSS提供商可能决定将前缀更改为"yahoo",如果您的脚本引用"media"前缀,您的脚本将停止工作.但是,如果使用命名空间名称,则无论前缀如何,它都将继续工作.


Bjö*_*örn 5

SimpleXML在处理名称空间方面非常糟糕。您有两种选择:最简单的技巧是将提要的内容简单地读入字符串并替换名称空间。

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

$rss = simplexml_load_string($feed);
...
Run Code Online (Sandbox Code Playgroud)

现在,您可以thumbnail直接访问元素。

更为优雅(不是真的)的方法是找出名称空间使用的URI。如果您查看http://feeds.bbci.co.uk/news/england/rss.xml的源代码,则会看到它指向http://search.yahoo.com/mrss/

现在,您可以在children()SimpleXMLElement 的方法中使用此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/');
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • -1建议将朴素的字符串操作作为与内置名称空间处理相比的任何一种选项。不知道为什么您认为`children`方法是“相当糟糕”和“不优雅”的-您必须在某些地方告诉SimpleXML *您想要哪个名称空间;您甚至可以(自PHP 5.3起)使用XML前缀(`-&gt; children('media',true)`),尽管URI是唯一保证不会更改的标识符(如果XML生成略有不同)。 (6认同)