我使用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"/>
答案 0 :(得分: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'];
}
我将命名空间称为“媒体”命名空间,但这并不正确。命名空间名称是http://search.yahoo.com/mrss/
,“media”只是一个前缀,如果你愿意的话,是某种别名。请记住,重要的是http://search.yahoo.com/mrss/
是命名空间的真实名称。在某些时候,您的RSS提供商可能决定将前缀更改为“yahoo”,如果您的脚本引用“media”前缀,您的脚本将停止工作。但是,如果使用命名空间名称,则无论前缀如何,它都将继续工作。
答案 1 :(得分:3)
SimpleXML处理命名空间非常糟糕。您有两种选择:最简单的方法是简单地将feed的内容读入字符串并替换名称空间;
$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/');
...
}