首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP和XML基于属性查找节点以查找另一个属性或节点的索引

PHP和XML基于属性查找节点以查找另一个属性或节点的索引
EN

Stack Overflow用户
提问于 2014-01-22 20:51:03
回答 1查看 194关注 0票数 0

我正在尝试优化我为解析YouTube配置文件而编写的一个小php应用程序。输入一个YouTube用户名,该应用程序通过解析帐户配置文件的gdata查询返回的XML,返回上传的视频数量、收藏夹、订阅者等简单列表。例如,这个XML:

代码语言:javascript
复制
<?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" gd:etag="W/"C0EHSX47eCp7I2A9Wh5aEU4.""> 
<id>tag:youtube.com,2008:user:H5m_qmnr3dHOO8x7m7dtvw</id> 
<published>2006-06-15T22:59:11.000Z</published> 
<updated>2014-01-07T21:53:58.000Z</updated> 
<category scheme="http://schemas.google.com/g/2005#kind" term="http://gdata.youtube.com/schemas/2007#userProfile" /> 
<category scheme="http://gdata.youtube.com/schemas/2007/channeltypes.cat" term="DIRECTOR" /> 
<title>epontius</title> 
<summary>channel page of epontius</summary> 
<link rel="alternate" type="text/html" href="https://www.youtube.com/channel/UCH5m_qmnr3dHOO8x7m7dtvw" /> 
<link rel="self" type="application/atom+xml" href="https://gdata.youtube.com/feeds/api/users/H5m_qmnr3dHOO8x7m7dtvw?v=2" /> 
 <author> 
<name>epontius</name> 
<uri>https://gdata.youtube.com/feeds/api/users/epontius</uri> 
<yt:userId>H5m_qmnr3dHOO8x7m7dtvw</yt:userId> 
</author> 
<yt:channelId>UCH5m_qmnr3dHOO8x7m7dtvw</yt:channelId> 
<gd:feedLink rel="http://gdata.youtube.com/schemas/2007#user.subscriptions" href="https://gdata.youtube.com/feeds/api/users/epontius/subscriptions?v=2" countHint="161" /> 
<gd:feedLink rel="http://gdata.youtube.com/schemas/2007#user.liveevent" href="https://gdata.youtube.com/feeds/api/users/epontius/live/events?v=2" countHint="0" /> 
<gd:feedLink rel="http://gdata.youtube.com/schemas/2007#user.favorites" href="https://gdata.youtube.com/feeds/api/users/epontius/favorites?v=2" countHint="73" /> 
<gd:feedLink rel="http://gdata.youtube.com/schemas/2007#user.contacts" href="https://gdata.youtube.com/feeds/api/users/epontius/contacts?v=2" countHint="184" /> 
<gd:feedLink rel="http://gdata.youtube.com/schemas/2007#user.inbox" href="https://gdata.youtube.com/feeds/api/users/epontius/inbox?v=2" /> 
<gd:feedLink rel="http://gdata.youtube.com/schemas/2007#user.playlists" href="https://gdata.youtube.com/feeds/api/users/epontius/playlists?v=2" /> 
<gd:feedLink rel="http://gdata.youtube.com/schemas/2007#user.uploads" href="https://gdata.youtube.com/feeds/api/users/epontius/uploads?v=2" countHint="26" /> 
<gd:feedLink rel="http://gdata.youtube.com/schemas/2007#user.newsubscriptionvideos" href="https://gdata.youtube.com/feeds/api/users/epontius/newsubscriptionvideos?v=2" /> 
<gd:feedLink rel="http://gdata.youtube.com/schemas/2007#user.recentactivity" href="https://gdata.youtube.com/feeds/api/users/epontius/events?v=2" /> 
<yt:googlePlusUserId>105085469892080308187</yt:googlePlusUserId> 
<yt:location>US</yt:location> 
<yt:statistics lastWebAccess="1970-01-01T00:00:00.000Z" subscriberCount="245" videoWatchCount="0" viewCount="0" totalUploadViews="68815" /> 
<media:thumbnail url="https://yt3.ggpht.com/-N_Et9Qg1APc/AAAAAAAAAAI/AAAAAAAAAAA/VIuQ_GuzA0Q/s88-c-k-no/photo.jpg" /> 
<yt:userId>H5m_qmnr3dHOO8x7m7dtvw</yt:userId> 
<yt:username display="epontius">epontius</yt:username> 
</entry>

这个应用程序运行良好,但是YouTube经常会改变一些元素的顺序,或者在行中添加/删除项目,所以当我访问'countHint‘属性时,应用程序返回不正确的数据。例如:

代码语言:javascript
复制
$uploadscount = $gd->feedLink[6]->attributes();
$uploads = $uploadscount['countHint'];
echo 'Number of uploads: ' . '<span class="datatext">' . $uploads . '</span>' . '<br />';

在这种情况下会返回26。但是,如果feedLink行的数量或顺序发生变化,我会得到不正确的信息或错误,因为feedLink的索引号是硬编码的。每个feedLink似乎都有一个惟一的rel=属性,我希望能够使用rel=和某种循环(比如foreach )来搜索特定的rel值(即。rel = "http://gdata.youtube.com/schemas/2007#user.uploads“),然后能够获取它的countHint属性值,将其赋值给一个变量,或者至少获取它的节点索引号(在上传的情况下是6),然后访问适当的countHint属性。然后对我想要获取的数据的每个feedLink行和属性重复这样的操作。这样,在这些feedLink行被修改的情况下,它将更加精确和动态。我就是想不出该怎么做。feedLink元素是不同名称空间(gd)中的空元素,并且存在倍数,这使我对使用xpath感到有些困惑。我不停地返回空值,然后迷路了。如有任何建议,将不胜感激。

好的。我想多亏了你的建议我才有所进展。

代码语言:javascript
复制
  foreach ($gd->feedLink as $feedLink) {
           $attributes = $feedLink->attributes();
            if (strpos($attributes['rel'], '#user.uploads')) {
             $uploads = $attributes['countHint'];
             }

            elseif (strpos($attributes['rel'], '#user.favorites')) {
             $favs = $attributes['countHint'];
              }

            elseif (strpos($attributes['rel'], '#user.subscriptions')) {
             $subscriptions = $attributes['countHint'];
              }

            elseif (strpos($attributes['rel'], '#user.liveevent')) {
             $liveevents = $attributes['countHint'];
             }

           elseif (strpos($attributes['rel'], '#user.contacts')) {
            $friends = $attributes['countHint'];
             }
          }

这将返回我正在寻找的适当值,但我现在担心的是,我正在做额外的处理来执行循环,因为我假设每个循环都会测试每一行,而不管它是否已经在前一个循环中找到了该值?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-22 21:30:13

使用foreach解析XML数据是正确的。我只需要在每个strpos()上做一个feedlink,直到我找到uploads元素为止。那我会设置$uploadscount

就像这样,也许:

代码语言:javascript
复制
foreach ($gd->feedLink as $feedLink) {
  $attributes = $feedlink->attributes();
  if (strpos($attributes['rel'], '#user.uploads')) {
    $uploadscount = $attributes;
    break;
  }
  continue; 
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21293712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档