SimpleXML 返回多个对象,如何获取数据? [英] SimpleXML returning multiple objects, how can I get the data?

查看:28
本文介绍了SimpleXML 返回多个对象,如何获取数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using simpleXML to parse this xml file. It's a feed I'm using to access the YouTube API. I want to embed the most recent video in an object and display the next four thumbnails.

所以我在这方面使用 simplexml_load_file,使用 foreach 循环访问每个提要中的值.

So I'm using simplexml_load_file on this, going using a foreach loop to access the values in each feed.

我可以毫无问题地访问这些值,但我遇到了将每个视频存储在单独的 SimpleXMLElement 对象 中的问题.我无法控制我正在访问的对象,因为它们没有存储在数组中.所以我无法得到,比如 $thumb[4]$entry[4]->thumb.

I can access the values no problem, but I run into the problem that it stores each video in a separate SimpleXMLElement Object. I don't have any control over which object I'm accessing as they are not stored in an array. So I can't get, say, $thumb[4] or $entry[4]->thumb.

我尝试使用 SimpleXMLIterator,但无论出于何种原因,任何具有相同开头的值都呈现为空白.例如,视频可以有十一种变体:

I tried to use SimpleXMLIterator, but for whatever reason, any values that have the same beginning render as blank. For example, the video could have eleven variations of:

这些都将呈现为 [1]="", [2]="", [3]=""

And these would each render as [1]="", [2]="", [3]="", etc.

我很乐意为任何可以提供帮助的人提供更多信息!

I'll happily provide some more information to anyone who can help!

编辑

这是我的结果的 print_r.这是在单个变量上完成的,目的是让您了解我面临的结构问题.整个 print_r($entry) 将为 XML 文件中的每个节点提供变量.

Here is the print_r of my results. This is done on a single variable to give you an idea of the structure issue I'm facing. The entire print_r($entry) would give variables for each node in the XML file.

SimpleXMLElement Object
(
    [0] => 159
)
SimpleXMLElement Object
(
    [0] => 44
)

此外,print_r 只是在 PHP 块中进行测试.我实际上是想访问 HTML 中回声中的变量.

Also, the print_r is simply inside the PHP block for testing. I'm actually looking to access the variables within echoes in the HTML.

推荐答案

你遇到了命名空间和 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.IE.它的子元素并不是真正的 idupdatedcategory,而是 http://www.w3.org/2005/Atom:idhttp://www.w3.org/2005/Atom:updated 等等...
所以你不能通过$feed->id访问id元素,你需要方法SimpleXMLELement::children().它允许您指定要检索的子元素的命名空间.

The xmlns='http://www.w3.org/2005/Atom' sets the default namespace to http://www.w3.org/2005/Atom. I.e. its child elements are not really id, updated, category but http://www.w3.org/2005/Atom:id, http://www.w3.org/2005/Atom:updated and so on...
So you can't access the the id element via $feed->id, you need the method SimpleXMLELement::children(). It lets you specify the namespace of the child elements you want to retrieve.

例如

$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;.
但是随后您将点击 元素及其子元素 , 等等...,它们位于 xmlns:media='http://search.yahoo.com/mrss/' 命名空间中.

To get the id of the first entry element you can use echo $children->entry[0]->id;.
But then you'll hit the <media:group> element and its children <media:category, <media:player> and so on..., which are in the xmlns:media='http://search.yahoo.com/mrss/' namespace.

$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 来完成此操作,但这里有一个(简单、丑陋的)示例应用.

I'd probably do that within the browser with a lot more JavaScript, but here's a (simple, ugly) example app.

<?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 脚本可以弄清楚如何处理数据.

Edit 2: "And when I click the thumbnails, I'll use jQuery to load the video in the main space. Seems like I'll need precise access to node[#], right?"
If you're already using JavaScript/jQuery your PHP script (if needed at all) could simply return a (JSON encoded) array of all the data for all the video and your jQuery script could figure out what to do with the data.

这篇关于SimpleXML 返回多个对象,如何获取数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆