PHP: Parsing SimpleXML nodes with namespaces

SimpleXML is one of the easiest parsers to use, but when it comes to namespaces, things get just a little bit tricker.

You'll run into them when you're parsing media RSS feeds such as:

  • FlickR (media:thumbnail, media:category, media:content)
  • YouTube API (yt:duration, yt:statistics, gd:rating, gd:comments)
  • or Yahoo Weather (yweather:location, yweather:astronomy)

They might be a bit gay to deal with, but luckily it isn't too much harder.

9
Namespaces, almost as gay as this guy.

The trick is having to gather the namespace children before pulling the element you want.

Using this short sample XML from FlickR.

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:creativeCommons="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html"
xmlns:flickr="urn:flickr:">
<channel>
<item>
<title>発売中</title>
...
<dc:date.Taken>2010-06-13T13:08:52-08:00</dc:date.Taken>
<media:thumbnail url="http://farm6.static.flickr.com/5122/5370686057_cb21430ac5_s.jpg" height="75" width="75" />
...
</item>
</channel>
</rss>

You can use this PHP code to extract the "media:thumbnail" elements from the RSS item.

$entries = simplexml_load_file('http://api.flickr.com/services/feeds/photos_public.gne?tags=tokyo&format=rss_200');
$namespaces = $entries->getNamespaces(true);

foreach ($entries->channel->item as $feeditem) {
$thumbnail = $feeditem->children($namespaces['media'])->thumbnail;
$attr = $thumbnail->attributes();

echo '<pre>';
echo "URL = {$attr['url']}, width = {$attr['width']}, height = {$attr['height']}\n";
echo print_r($attr, true);
echo '</pre>';
}

The code was based off the source from PHPFreaks, but modified to avoid using the URI of namespaces as it makes the code ugly.

Enjoy!

[ Source ]

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog