使用SimpleXML PHP访问XML中的命名空间冒号节点

时间:2011-07-28 11:25:29

标签: php xml parsing rss simplexml

这类似于我发布的一个问题,但我已经扩展了,因为这必须是可以解决的。

我正在尝试从此RSS Feed中访问评级和viewCount。现在,这些命名空间用yt:和gd: - 但是命名空间引用是来自youtube的feed的404,所以它似乎失败了。请帮忙吗?

我正在尝试使用: -

$ytFeed->children('http://gdata.youtube.com/schemas/2007')->statistics->attributes('viewCount'));

但它失败了......它确实像通常那样工作,例如我可以访问媒体:

$ytFeed->children('http://search.yahoo.com/mrss/')->group->category);

这是原始RSS,请查看这些节点的底部: -

<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/' xmlns:gd='http://schemas.google.com/g/2005' xmlns:yt='http://gdata.youtube.com/schemas/2007'>
    <id>http://gdata.youtube.com/feeds/api/videos/tDJFDsZFw2E</id>
    <published>2009-03-02T07:02:49.000Z</published>
    <updated>2011-07-19T06:57:29.000Z</updated>
    <category scheme='http://schemas.google.com/g/2005#kind' term='http://gdata.youtube.com/schemas/2007#video' />
    <category scheme='http://gdata.youtube.com/schemas/2007/categories.cat' term='Music' label='Music' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Other Lives' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Jesse Tabish' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Jenny Hsu' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Jupiter Hotel' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Portland' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='music' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='band' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='interview' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='mf magazine' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='fashion' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='hotel room' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='doug fir lounge' />
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='erik schultz' />
    <title type='text'>Other Lives</title>
    <content type='text'>We sat down with Jesse Tabish and Jenny Hsu from Other Lives at the Jupiter Hotel in Portland, OR. We love these guys. Check them out at myspace.com/otherlivesVisit mf magazine at musicfashionmagazine.com or myspace.com/musicfashion</content>
    <link rel='alternate' type='text/html' href='http://www.youtube.com/watch?v=tDJFDsZFw2E&amp;feature=youtube_gdata' />
    <link rel='http://gdata.youtube.com/schemas/2007#video.responses' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/tDJFDsZFw2E/responses' />
    <link rel='http://gdata.youtube.com/schemas/2007#video.related' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/tDJFDsZFw2E/related' />
    <link rel='self' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/tDJFDsZFw2E' />
    <author>
        <name>mfmagazine</name>
        <uri>http://gdata.youtube.com/feeds/api/users/mfmagazine</uri>
        </author>
    <gd:comments>
        <gd:feedLink href='http://gdata.youtube.com/feeds/api/videos/tDJFDsZFw2E/comments' countHint='16' />
        </gd:comments>
    <media:group>
        <media:category label='Music' scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>Music</media:category>
        <media:content url='http://www.youtube.com/v/tDJFDsZFw2E?f=videos&amp;app=youtube_gdata' type='application/x-shockwave-flash' medium='video' isDefault='true' expression='full' duration='600' yt:format='5' />
        <media:content url='rtsp://v3.cache3.c.youtube.com/CiILENy73wIaGQlhw0XGDkUytBMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp' type='video/3gpp' medium='video' expression='full' duration='600' yt:format='1' />
        <media:content url='rtsp://v6.cache3.c.youtube.com/CiILENy73wIaGQlhw0XGDkUytBMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp' type='video/3gpp' medium='video' expression='full' duration='600' yt:format='6' />
        <media:description type='plain'>We sat down with Jesse Tabish and Jenny Hsu from Other Lives at the Jupiter Hotel in Portland, OR. We love these guys. Check them out at myspace.com/otherlivesVisit mf magazine at musicfashionmagazine.com or myspace.com/musicfashion</media:description>
        <media:keywords>Other Lives, Jesse Tabish, Jenny Hsu, Jupiter Hotel, Portland, music, band, interview, mf magazine, fashion, hotel room, doug fir lounge, erik schultz</media:keywords>
        <media:player url='http://www.youtube.com/watch?v=tDJFDsZFw2E&amp;feature=youtube_gdata_player' />
        <media:thumbnail url='http://i.ytimg.com/vi/tDJFDsZFw2E/0.jpg' height='240' width='320' time='00:05:00' />
        <media:thumbnail url='http://i.ytimg.com/vi/tDJFDsZFw2E/1.jpg' height='90' width='120' time='00:02:30' />
        <media:thumbnail url='http://i.ytimg.com/vi/tDJFDsZFw2E/2.jpg' height='90' width='120' time='00:05:00' />
        <media:thumbnail url='http://i.ytimg.com/vi/tDJFDsZFw2E/3.jpg' height='90' width='120' time='00:07:30' />
        <media:title type='plain'>Other Lives</media:title>
        <yt:duration seconds='600' />
        </media:group>
    <gd:rating average='5.0' max='5' min='1' numRaters='17' rel='http://schemas.google.com/g/2005#overall' />
    <yt:statistics favoriteCount='10' viewCount='3572' />
    </entry>

3 个答案:

答案 0 :(得分:5)

在调用children函数时简单传递namespace参数

$nodes = $xml->children('gd', true);

请参阅手册:http://www.php.net/manual/en/simplexmlelement.children.php

答案 1 :(得分:5)

好的,第一个问题是您滥用attributes方法:

$simpleXML->statistics->attributes('viewCount'));

在上面(从你的例子中解释)你传递了你想要的属性的名称,这不是attributes接受的参数。相反,上面将返回属性本身具有statistics命名空间的viewCount元素的所有属性,因为该方法需要第一个参数(如果已设置)作为属性的命名空间。

如果您将属性作为元素的数组进行访问,则代码将起作用,如下所示:

$ytFeed->children('http://gdata.youtube.com/schemas/2007')->statistics['viewCount'];

如果您希望每次都避免使用完整的命名空间uri和children方法,可以使用getNamespaces方法将所有命名空间映射到一个数组,然后将子映射映射到通过children方法命名空间到一个对象,如:

$namespaces = $ytFeed->getNameSpaces(true);
$yt = $ytFeed->children($namespaces['yt']);
$yt->statistics['viewCount'];

// Access all media: namespaced group elements like in your "working" example:
$media = $ytFeed->children($namespaces['media']);
$media->group->category;

我意识到这已经超过2年了,并且答案被接受了,但是接受的答案实际上只是一个更好的记录和更直观的替代方案,但是并没有告诉其他人发现这个问题的实际方法是SimpleXML,最终只需要额外的两行代码到DOMDocument的6-8个额外行和不同的扩展,这可能会误导未来读者认为无法用SimpleXML完成。它可以,而且很容易,但不是很明显。

答案 2 :(得分:2)

使用DomDocumentDomXpath

error_reporting(E_ALL ^ E_STRICT);
ini_set('display_errors', 'on');

$dom = new DomDocument;
$dom->load('data.xml');

$xpath = new DomXpath($dom);
$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
$xpath->registerNamespace('media', 'http://search.yahoo.com/mrss/');
$xpath->registerNamespace('gd', 'http://schemas.google.com/g/2005');
$xpath->registerNamespace('yt', 'http://gdata.youtube.com/schemas/2007');

$favoriteCountAttr = $xpath->query('/atom:entry/yt:statistics/@favoriteCount')->item(0);
if ($favoriteCountAttr instanceof DomAttr) {
    echo $favoriteCountAttr->nodeValue; // output: 10
}