This is similar to a question I\'ve posted, but I\'ve broadened out as this has got to be solvable.
I am trying to access rating and viewCount from this rss feed. No
Using DomDocument and DomXpath:
error_reporting(E_ALL ^ E_STRICT);
ini_set('display_errors', 'on');
$dom = new DomDocument;
$dom->load('data.xml');
$xpath = new DomXpath($dom);
$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
$xpath->registerNamespace('media', 'http://search.yahoo.com/mrss/');
$xpath->registerNamespace('gd', 'http://schemas.google.com/g/2005');
$xpath->registerNamespace('yt', 'http://gdata.youtube.com/schemas/2007');
$favoriteCountAttr = $xpath->query('/atom:entry/yt:statistics/@favoriteCount')->item(0);
if ($favoriteCountAttr instanceof DomAttr) {
echo $favoriteCountAttr->nodeValue; // output: 10
}
Okay, first problem is that you are misusing the attributes method:
$simpleXML->statistics->attributes('viewCount'));
in the above (paraphrased from your example) you pass in the name of the attribute you want, which is not the parameter that attributes
accepts. The above, instead, would return all attributes of the statistics
element where the attribute itself had a namespace of viewCount
, because the method expects the first parameter, if one is set, to be the attribute's namespace.
Your code would work if you instead accessed the attributes as an array of the element, like so:
$ytFeed->children('http://gdata.youtube.com/schemas/2007')->statistics['viewCount'];
If you want to avoid using the full namespace uri and the children
method every time, you could simplify by using the getNamespaces
method to map all namespaces to one array and then mapping the children with that namespace to one object via the children
method, like:
$namespaces = $ytFeed->getNameSpaces(true);
$yt = $ytFeed->children($namespaces['yt']);
$yt->statistics['viewCount'];
// Access all media: namespaced group elements like in your "working" example:
$media = $ytFeed->children($namespaces['media']);
$media->group->category;
I realize this is over 2 years old and an answer was accepted, but the accepted answer is really just an alternative that is better documented and more intuitive, but does not tell others who find this question the actual way to achieve this with SimpleXML, which in the end requires only an extra two lines of code to the DOMDocument's 6-8 extra lines and a different extension, which may mislead future readers into thinking it can't be done with SimpleXML. It can, and it's easy, just not very obvious.
Simple pass the namespace argument when calling children function
$nodes = $xml->children('gd', true);
See the manual: http://www.php.net/manual/en/simplexmlelement.children.php