Использование SimpleXML для чтения RSS-каналов - PullRequest
20 голосов
/ 03 февраля 2011

Я использую 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"/>  

Ответы [ 2 ]

19 голосов
/ 04 февраля 2011

Как вы уже знаете, SimpleXML позволяет выбрать дочерний узел, используя оператор свойства объекта ->, или атрибут узла, используя доступ к массиву ['name']. Это здорово, но операция работает, только если то, что вы выбираете, принадлежит к тому же пространству имен .

Если вы хотите "hop" из пространства имен в другое, вы можете использовать методы children() или attributes(). В вашем случае это немного сложнее, потому что у вас есть <item/> в глобальном пространстве имен, искомый узел находится в пространстве имен «media» *, а затем атрибуты снова находятся в глобальном пространстве имен (они не являются с префиксом.) Таким образом, используя обычную запись объекта / массива, вам придется "hop" дважды:

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 ", но это не совсем правильно. Имя пространства имен - http://search.yahoo.com/mrss/, а «media» - это просто префикс, какой-то псевдоним, если хотите. Важно помнить, что http://search.yahoo.com/mrss/ - это настоящее имя пространства имен. В какой-то момент ваш провайдер RSS может решить изменить префикс, скажем, на «Yahoo», и ваш скрипт перестанет работать, если ваш скрипт ссылается на префикс «media». Однако если вы используете имя пространства имен, оно будет работать независимо от префикса.

4 голосов
/ 03 февраля 2011

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/.

Теперь вы можете использовать этот URI в методе children() элемента SimpleXMLElement, чтобы получить содержимоеСМИ: элемент эскиза;

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