使用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/mediahttp://img.dovov.com51078000/jpg/_51078953_226alanpotbury.jpg"/>
SimpleXML在处理名称空间方面很糟糕。 您有两个select:最简单的方法是简单地将提要的内容读入string并replace名称空间;
$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来获取媒体内容:缩略图元素;
$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/'); ... }
正如你所知,SimpleXML允许你使用对象属性操作符->
或者使用数组access ['name']
select一个节点的子节点。 这很好,但只有当你select属于同一个命名空间时 ,该操作才有效。
如果你想从一个名字空间跳到另一个名字空间,你可以使用children()
或者attributes()
方法。 在你的情况下,这是有点棘手,因为你有全局命名空间中的<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']; }
*注意
我把这个命名空间称为“媒体”命名空间,但这不是真的正确。 命名空间的名称是http://search.yahoo.com/mrss/
,“媒体”只是一个前缀,如果你愿意,可以是某种别名。 要记住的重点是http://search.yahoo.com/mrss/
是命名空间的真实名称。 在某些情况下,您的RSS提供商可能会决定将前缀更改为“yahoo”,如果您的脚本引用“媒体”前缀,则脚本将停止工作。 但是,如果使用名称空间名称,则无论前缀如何,都将继续工作。