使用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”,如果您的脚本引用“媒体”前缀,则脚本将停止工作。 但是,如果使用名称空间名称,则无论前缀如何,都将继续工作。