SimpleXML 返回多个对象,如何获取数据?

发布于 2024-08-20 03:03:14 字数 982 浏览 4 评论 0 原文

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

因此,我对此使用 simplexml_load_file,使用 foreach 循环来访问每个 feed 中的值。

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

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

这些将分别呈现为 [1]=""[2]=""[3]="" 等。

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

编辑

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

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

另外, print_r 只是在 PHP 块内进行测试。我实际上希望访问 HTML 中 echo 中的变量。

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.

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

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.

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:

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

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

Edit

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
)

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烟花肆意 2024-08-27 03:03:14

您遇到了命名空间和 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 。即它的子元素实际上并不是 idupdatedcategory 而是 http://www.w3.org/2005/Atom :idhttp://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;
但随后您将点击 元素及其子元素 等等...,它们位于 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 脚本可以确定如何处理这些数据。

You ran into the problem of namespaces and SimpleXML. The feed starts with

<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'>

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.

For example,

$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;

Currently prints 2010-02-06T05:23:33.858Z.

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";
}

(Currently) prints

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

Edit: 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
    );
  }
}

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.

小红帽 2024-08-27 03:03:14
$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 />';
}
$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 />';
}
沉睡月亮 2024-08-27 03:03:14

尝试 $sxml->entry[4]->thumb 或与此相关的内容。

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

基本上 $sxml->entry 是一个数组SimpleXMLElement 对象。当您 foreach 它们时,您将遍历每个对象并将其分配给 $entry,以便 $entry = $sxml->entry[0] 及以上。

你可以这样:

print_r($sxml);

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

Try $sxml->entry[4]->thumb or something to that regard.

AKA, to access the first entries ID, you would go $sxml->entry[4]->id

Basically $sxml->entry is an array of SimpleXMLElement Objects. When you foreach them, you are going through each object and assigning it to $entry, so that $entry = $sxml->entry[0] and upwards.

You can go like this:

print_r($sxml);

to see the ENTIRE structure. And that will tell you what you need to use to access it.

她比我温柔 2024-08-27 03:03:14

最后,我执行了两个 foreach 循环,其中一个循环运行 XML 提要,显示最新的 one 条目。然后,我回显周围的物体来播放视频。

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

现在,当我单击缩略图视频时,JavaScript 会处理将参数传递到主条目。现在,如何在收到参数后重新加载该主对象,我愿意接受想法。

In the end, I did two foreach loops, one running through an XML feed showing the most recent one entry. Then, I echoed out the object around this to play the vide.

In the other, I ran through the most recent four entries, returning list elements for a list of thumbnails.

Now, when I click on a thumbnail video, javascript handles passing the parameters to the main entry. Now, how to reload that main object upon receiving the parameters, I'm open to ideas.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文