rostamiani
rostamiani

Reputation: 3265

Getting media url attribute from SimpleXMLElement object

I want to get 'url' attribute from 'media:content' tag of a RSS using simplexml. I searched the net for hours but cannot get it to work. This is the code:

<?php
$rss ='<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <item>
            <media:content url="http://blog.com/image1.jpg" width="661" height="310"/>
        </item>
    </channel>
</rss>';

$xml = simplexml_load_string($rss);
$url = $xml->children('media', true)->content;

var_dump($xml);
var_dump($url); // <- This is object(SimpleXMLElement)[3]
var_dump($url['url']); // <- This is NULL

The $url is NULL. ->content returns a SimpleXMLElement but it hasn't any url attribute!

Upvotes: 0

Views: 1812

Answers (3)

Nigel Ren
Nigel Ren

Reputation: 57141

Firstly you have to make sure that your fetching the right content element, so make sure that you fetch the full path of the content node (note the extra path in setting up the $url variable). Then there are some oddities of fetching the attributes of a namespaced element (I believe they do not have a namespace themselves), to access them you have to use the attributes() method and then fetch the element using ['url']. You can try the added options...

$xml = simplexml_load_string($rss);
$url = $xml->channel->item->children('media', true)->content;

var_dump($xml);
var_dump($url); // <- This is object(SimpleXMLElement)[3]
var_dump($url['url']); // <- This is NULL
var_dump($url->attributes()['url']);
echo "url-".(string)$url->attributes()['url'].PHP_EOL;

The last two lines give you...

class SimpleXMLElement#6 (1) {
  public ${0} =>
  string(26) "http://blog.com/image1.jpg"
}
url-http://blog.com/image1.jpg

(echo will cast the value to a string anyway, but I put this in just in case you try assigning the value and wanted the value rather than the SimpleXMLElement object)

Upvotes: 2

The fourth bird
The fourth bird

Reputation: 163642

You could use SimpleXMLElement xpath with for example this expression to get the media:content element:

/rss/channel/item/media:content

$xml = simplexml_load_string($rss);
$urls = $xml->xpath('/rss/channel/item/media:content');

// Get url from the first match
echo $urls[0]->attributes()->url;

// Loop all the matches
foreach ($urls as $url) {
    echo $url->attributes()->url;
}

Php demo output

Or you can loop though the children for this item:

foreach ($xml->channel->item->children("media", true) as $child) {
    echo $child->attributes()->url;
}

Php demo output

Upvotes: 1

Juan
Juan

Reputation: 5589

The problem is that you are ignoring the media namespace.

In this link you can find more about how to address tags with a namespace specified.

In the example the namespace is passed to the children member function to scope the media:content tag.

$xml = simplexml_load_string($rss);
$url = $xml->children('http://search.yahoo.com/mrss/')->content;

var_dump($xml);
var_dump($url); // <- This is object(SimpleXMLElement)[3]
var_dump($url['url']); // <- This is NULL

Upvotes: 0

Related Questions