我正在使用simpleXML来解析this xml file。这是我用来访问YouTube API的Feed。我想在对象中嵌入最新的视频并显示接下来的四个缩略图。
所以我在此使用simplexml_load_file
,使用foreach
循环访问每个Feed中的值。
我可以毫无问题地访问这些值,但是我遇到了将每个视频存储在单独的SimpleXMLElement Object
中的问题。我无法控制我正在访问哪个对象,因为它们没有存储在数组中。所以我不能说,$thumb[4]
或$entry[4]->thumb
。
我尝试使用SimpleXMLIterator
,但无论出于何种原因,任何具有相同开头的值都会呈现为空白。例如,视频可能有11种变体:
这些会呈现为[1]=""
,[2]=""
,[3]=""
等。
我很乐意为可以提供帮助的任何人提供更多信息!
修改
这是我的结果的print_r。这是在一个变量上完成的,让您了解我面临的结构问题。整个print_r($ entry)将为XML文件中的每个节点提供变量。
SimpleXMLElement Object
(
[0] => 159
)
SimpleXMLElement Object
(
[0] => 44
)
此外,print_r只是在PHP块内部进行测试。我实际上是想在HTML中的回声中访问变量。
答案 0 :(得分:7)
你遇到了namespaces and SimpleXML的问题。 Feed以
开头<feed xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:gd='http://schemas.google.com/g/2005' xmlns:yt='http://gdata.youtube.com/schemas/2007'>
xmlns='http://www.w3.org/2005/Atom'
将默认命名空间设置为http://www.w3.org/2005/Atom
。即它的子元素实际上不是id
,updated
,category
,而是http://www.w3.org/2005/Atom:id
,http://www.w3.org/2005/Atom:updated
等等......
因此,您无法通过$feed->id
访问id元素,您需要方法SimpleXMLELement::children()。它允许您指定要检索的子元素的命名空间。
例如,
$feed = simplexml_load_file('http://gdata.youtube.com/feeds/api/videos?author=ofcoursegolf&max-results=5&prettyprint=true');
$children = $feed->children('http://www.w3.org/2005/Atom');
echo $children->updated;
目前正在打印2010-02-06T05:23:33.858Z
。
要获取第一个条目元素的ID,您可以使用echo $children->entry[0]->id;
但是,您将点击<media:group>
元素及其子元素<media:category
,<media:player>
等等,它们位于xmlns:media='http://search.yahoo.com/mrss/'
命名空间中。
$feed = simplexml_load_file('http://gdata.youtube.com/feeds/api/videos?author=ofcoursegolf&max-results=5&prettyprint=true');
$group = $feed->children('http://www.w3.org/2005/Atom')
->entry[0]
->children('http://search.yahoo.com/mrss/')
->group
->children('http://search.yahoo.com/mrss/')
;
echo $group->player->attributes()->url, "\n";
foreach( $group->thumbnail as $thumb) {
echo 'thumb: ', $thumb->attributes()->url, "\n";
}
(目前)打印
http://www.youtube.com/watch?v=ikACkCpJ-js&feature=youtube_gdata
thumb: http://i.ytimg.com/vi/ikACkCpJ-js/2.jpg
thumb: http://i.ytimg.com/vi/ikACkCpJ-js/1.jpg
thumb: http://i.ytimg.com/vi/ikACkCpJ-js/3.jpg
thumb: http://i.ytimg.com/vi/ikACkCpJ-js/0.jpg
编辑:我可能会在浏览器中使用更多JavaScript进行此操作,但这是一个(简单,丑陋)示例应用程序。
<?php
//define('TESTENV' , true);
function getFeed($author) {
// <-- add caching here if needed -->
if ( !defined('TESTENV') ) {
$url = sprintf('http://gdata.youtube.com/feeds/api/videos?author=%s&max-results=5',
urlencode($author)
);
}
else {
$url = 'feed.xml';
}
return simplexml_load_file($url);
}
$feed = getFeed('jonlajoie');
if ( !isset($_GET['id']) ) {
$selected = '';
}
else {
$selected = $_GET['id'];
printf ('
<object width="425" height="344">
<param name="movie" value="http://www.youtube.com/v/%s"></param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always">
</param>
<embed src="http://www.youtube.com/v/%s" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
</object>',
htmlspcialchars($selected), htmlspcialchars($selected)
);
}
$item = 0;
foreach( $feed->children('http://www.w3.org/2005/Atom')->entry as $entry ) {
$entryElements = $entry->children('http://www.w3.org/2005/Atom');
$groupElements = $entry
->children('http://search.yahoo.com/mrss/')
->group
->children('http://search.yahoo.com/mrss/')
;
if ( !preg_match('!^http://gdata.youtube.com/feeds/api/videos/([^/]+)!', $entryElements->id, $m) ) {
// google can choose whatever id they want. But this is only a simple example....
die('unexpected id: '.htmlspecialchars($entryElements->id));
}
$id = $m[1];
if ( $selected!==$id ) {
printf('<a href="?id=%s"><img src="%s" /></a>',
urlencode($id),
$groupElements->thumbnail[0]->attributes()->url
);
}
}
编辑2:“当我点击缩略图时,我将使用jQuery在主空间中加载视频。好像我需要精确访问节点[#],对吧?”
如果您已经在使用JavaScript / jQuery,那么PHP脚本(如果需要的话)可以简单地返回所有视频的所有数据的(JSON编码)数组,并且您的jQuery脚本可以找出如何处理数据。 / p>
答案 1 :(得分:2)
$doc = new DOMDocument();
$doc->loadXML(file_get_contents('http://gdata.youtube.com/feeds/api/videos?author=ofcoursegolf&max-results=5&prettyprint=true'));
$xpd = new DOMXPath($doc);
$xpd->registerNamespace('atom', "http://www.w3.org/2005/Atom");
false&&$node = new DOMElement();//this is for my IDE to have intellysense
$result = $xpd->query('//atom:feed/atom:entry[1]/media:group/media:thumbnail');
foreach($result as $node){
echo $node->getAttribute('url').'<br />';
}
echo "more results <br />";
$result = $xpd->query('//atom:feed/atom:entry[1]/media:group/media:thumbnail[1]');
foreach($result as $node){
echo $node->getAttribute('url').'<br />';
}
答案 2 :(得分:1)
尝试$sxml->entry[4]->thumb
或类似的事情。
AKA,要访问第一个条目ID,您可以转到$sxml->entry[4]->id
基本上$sxml->entry
是一个SimpleXMLElement Object
的数组。当您预先处理它们时,您将浏览每个对象并将其分配给$entry
,以便$entry = $sxml->entry[0]
及以上。
你可以这样:
print_r($sxml);
查看整个结构。这将告诉您需要使用什么来访问它。
答案 3 :(得分:0)
最后,我做了两个foreach循环,一个循环显示最近的一个条目的XML Feed。然后,我回应了周围的物体来播放视频。
另一方面,我浏览了最近的四个条目,返回列表元素以获取缩略图列表。
现在,当我点击缩略图视频时,javascript会将参数传递给主条目。现在,如何在收到参数时重新加载主要对象,我愿意接受这些想法。