2

我正在使用 simpleXML 来解析这个 xml 文件。这是我用来访问 YouTube API 的提要。我想在一个对象中嵌入最新的视频并显示接下来的四个缩略图。

所以我正在使用simplexml_load_file这个,使用foreach循环来访问每个提要中的值。

我可以毫无问题地访问这些值,但我遇到了将每个视频存储在单独的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 中回声中的变量。

4

4 回答 4

7

您遇到了名称空间和 SimpleXML的问题。提要以

<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...
所以你不能通过 id 访问元素$feed->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 脚本可以弄清楚如何处理这些数据。

于 2010-02-06T06:11:43.220 回答
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 />';
}
于 2010-02-06T06:39:36.773 回答
1

尝试$sxml->entry[4]->thumb或在这方面的东西。

AKA,要访问第一个条目 ID,你会去$sxml->entry[4]->id

基本上$sxml->entry是一个SimpleXMLElement Objects数组。当你 foreach 它们时,你正在遍历每个对象并将其分配给$entry, so that$entry = $sxml->entry[0]和 ups 。

你可以这样:

print_r($sxml);

查看整个结构。这将告诉您访问它需要使用什么。

于 2010-02-06T04:39:16.140 回答
0

最后,我做了两个 foreach 循环,一个通过一个显示最新条目的 XML 提要运行。然后,我呼应了这个周围的物体来播放视频。

另一方面,我浏览了最近的四个条目,返回缩略图列表的列表元素。

现在,当我单击缩略图视频时,javascript 会处理将参数传递给主条目。现在,如何在接收到参数后重新加载该主对象,我对想法持开放态度。

于 2010-02-07T06:46:06.003 回答