使用 SimpleXML 读取 RSS 源

2022-08-30 19:14:43

我正在使用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"/>  

答案 1

如您所知,SimpleXML 允许您使用对象属性运算符选择节点的子节点,或使用数组访问选择节点的属性。这很好,但只有在您选择的内容属于同一命名空间时,该操作才有效。->['name']

如果要从一个命名空间“跃升”到另一个命名空间,可以使用 children()attributes() 方法。在你的例子中,这有点棘手,因为你在全局命名空间中,你要查找的节点在“media”命名空间*中,然后属性再次在全局命名空间中(它们没有前缀)。因此,使用正常的对象/数组表示法,您必须“跳”两次:<item/>

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'];
}

*备注

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


答案 2

SimpleXML在处理命名空间方面非常糟糕。您有两个选择:最简单的技巧是简单地将源的内容读取到字符串中并替换命名空间;

$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 的方法中使用此 URI 来获取 media:thumbnail 元素的内容;children()

$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/');
    ...
}

推荐