Xpoint
   [напомнить пароль]

Парисим RSS: как обратиться к элементу xml?

Метки: [без меток]
2008-12-01 22:07:15 [обр] Александр М(0/4)[досье]

CMS Wordpress транслирует rss-ленту комментариев, где среди прочего, есть вот такая конструкция:

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
        xmlns:content="http://purl.org/rss/1.0/modules/content/"
        xmlns:dc="http://purl.org/dc/elements/1.1/"
        xmlns:atom="http://www.w3.org/2005/Atom"
        >
<channel>
        <title>Комментарии для WP</title>
        <atom:link href="http://my.blog/comments/feed/" rel="self" type="application/rss+xml" />
        <link>http://my.blog</link>
        <description>My Head Blog</description>
        <pubDate>Sun, 30 Nov 2008 23:22:48 +0000</pubDate>
        <generator>http://wordpress.org/?v=2.6.5</generator>
        <item>
                <title>Комментарий на Тестовая публикация от admin</title>
                <link>http://my.blog/2008/11/30/1/#comment-37</link>
                <dc:creator>admin</dc:creator>
                <pubDate>Sat, 08 Nov 2008 22:38:47 +0000</pubDate>
                <guid isPermaLink="false">http://my.blog/2008/11/30/1/#comment-37</guid>
                <description>Тестовый комментарий</description>
                <content:encoded><![CDATA[<p>Тестовый комментарий</p>]]></content:encoded>
        </item>
</channel>
</rss>

Из PHP я пытаюсь обратиться к элементу <dc:creator>admin</dc:creator> и получаю (PHP: третья строка) ошибку. Делаю так:

<?php $rss = simplexml_load_file('http://my.blog/comments/feed/'); ?>
<?foreach($rss->channel->item as $item):?>
        <?=$item->dc:creator?><br />
        <a href="<?=$item->link?>" title="<?=$item->title?>"><?=$item->description?></a><hr>
<?endforeach?>

Подскажите как правильно вывести имя автора комментария из xml-примера выше?

Спасибо

спустя 1 час 9 минут [обр] MiRacLe(0/77)[досье]
foreach ($rss->channel->item as $item) {
    $ns_dc = $item->children('http://purl.org/dc/elements/1.1/');
    var_dump($ns_dc);
}
спустя 1 час 22 минуты [обр] Александр М(0/4)[досье]

Жуткий синтаксис, но работает. Спасибо!

Скажите: скрипт каждый раз к purl.org обращаться будет или тут в другом дело?

спустя 5 минут [обр] MiRacLe(0/77)[досье]
Тут дело в документации. Обращаться не будет.
спустя 45 минут [обр] Александр М(0/4)[досье]

В самом последнем комментарии (от 06-Sep-2008 04:39 по «Вашей» ссылке) описан мой случай, но я так и не понял для чего у children эта ссылка. Видимо, что-то связанное с особенностями xml, который я не знаю.

p.s.: вопрос решен, тему можно закрыть.

спустя 8 минут [обр] Александр М(0/4)[досье]
Подумав немного над примером, я у себя автора из этого элемента <dc:creator>admin</dc:creator> вывел так: <?=$item->children('http://purl.org/dc/elements/1.1/')->creator?> - работает. Кстати <?=$item->children('http://purl.org/dc/elements/1.1/')?> (без creator) - тоже работает. Но, видимо, последний пример не совсем корректен.
спустя 6 часов [обр] MiRacLe(0/77)[досье]
спустя 7 часов [обр] Александр М(0/4)[досье]

С «Пространством имен» кое, что прояснилось. Остался неясным такой момент: в начале xml документа мы уже связали префикс :dc с пространством http://purl.org/dc/elements/1.1/. Так зачем мы это делали, если в php мы используем пространство, а не связанный с ним префикс? Я так понимаю, что объявление было сделано для удобства?

WIKI пишет:

В объявление можно также включить короткий префикс, которым будет однозначно идентифицироваться пространство имён каждого элемента

Не ужели к элементу creator нельзя обратиться через префикс, а не через пространство имен?

спустя 4 минуты [обр] Lynn «Кофеман»(52/571)[досье]
Вот так $item->dc:creator точно нельзя, двоеточие не входит в список символов разрешённых в идентификаторах. Попробуйте $item->{"dc:creator"}
спустя 7 минут [обр] MiRacLe(0/77)[досье]
не пробуйте
спустя 33 минуты [обр] MiRacLe(0/77)[досье]
Если напрягает писать длинный namespace, можете захардкодить себе коротенькую константу или делать что-то вроде:
$ns = $rss->getDocNamespaces();
...
$author = $item->children($ns['dc'])->creator;
спустя 1 день 21 час [обр] Александр М(0/4)[досье]
getDocNamespaces() — здорово! Так и сделал. Спасибо!
Powered by POEM™ Engine Copyright © 2002-2005