Accessing namespace colon nodes in XML with SimpleXML PHP

前端 未结 3 774
梦如初夏
梦如初夏 2020-12-22 08:11

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

相关标签:
3条回答
  • 2020-12-22 08:49

    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
    }
    
    0 讨论(0)
  • 2020-12-22 09:04

    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.

    0 讨论(0)
  • 2020-12-22 09:05

    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

    0 讨论(0)
提交回复
热议问题