Accessing XML properties that have colon in the na

2019-06-10 07:27发布

问题:

This question already has an answer here:

  • SimpleXML and namespaces 3 answers

I'm trying to get video info from a YouTube XML feed such as the title and thumbnail URL.

Let's take this feed as an example: http://gdata.youtube.com/feeds/api/videos/CevxZvSJLk8

Here's the code I have now:

$videoURL = 'http://gdata.youtube.com/feeds/api/videos/CevxZvSJLk8';
$sxml = simplexml_load_file($videoURL);
print_r($sxml);

However, that doesn't seem to be including the media:group part of the xml sheet.

Essentially, I'm trying to get these two values:

entry -> media:group -> media:title
entry -> media:group -> media:thumbnail

EDIT: This is the solution I ended up going with from reading other similar questions.

$videoTitle = $sxml->children('media', true)->group->title;
$videoThumbnail = $sxml->children('media', true)->group->thumbnail->attributes()->url;

回答1:

The colon in a tag name separates the namespace prefix from the local element or attribute name. The feed in the question has several namespaces.

  • http://www.w3.org/2005/Atom
  • http://purl.org/atom/app# with prefix app
  • http://search.yahoo.com/mrss/ with prefix media
  • http://schemas.google.com/g/2005 with prefix gd
  • http://gdata.youtube.com/schemas/2007 with prefix yt

The namespace prefix is an alias for the actual namespace, it is only valid for the document and can change for child nodes. The next feed could use the prefix atom for http://www.w3.org/2005/Atom. So depending on the namespace prefix from the document is a bad idea.

If you use Xpath fo fetch the elements from a document, you can register your own prefixes for the used namespaces. The following example fetches the media rss title and the url of the large thumbnail directly as strings. If an element does not exists, it will return an empty string.

$videoURL = 'http://gdata.youtube.com/feeds/api/videos/CevxZvSJLk8';
$dom = new DOMDocument();
$dom->load($videoURL);

$xpath = new DOMXPath($dom);
$xpath->registerNamespace('mrss', 'http://search.yahoo.com/mrss/');

var_dump(
  $xpath->evaluate('string(//mrss:title)', NULL, FALSE),
  $xpath->evaluate('string(//mrss:thumbnail[@width="480"]/@url)', NULL, FALSE)
);

Output:

string(28) "Katy Perry - Roar (Official)"
string(40) "http://i1.ytimg.com/vi/CevxZvSJLk8/0.jpg"