Search code examples
phpxmlsimplexml

How to easily parse XML documents with namespaces in PHP using SimpleXML?


I am trying to parse YouTube's top 15 videos feed. An excerpt of the feed I am trying to parse looks like the following:

<entry>
    <title>The Title</title>
    <link href="http://example.com" />
    <media:thumbnail url="http://example.com/image.png" />
    <media:description>The Description</media:description>
    <media:statistics views="123456" />
    <pubDate>29/01/2017</pubDate>
</entry>

I am unable to capture any of the values that use the tags beginning with <media:. I am using the following code to parse the data; commented lines are those that don't work.

foreach ($xml->entry as $val) {
    echo "<item>".PHP_EOL;
    echo "<title>".$val->title."</title>".PHP_EOL;
    echo "<link>".$val->link["href"]."</link>".PHP_EOL;
    //echo "<image>".$val->media:thumbnail["url"]."</image>".PHP_EOL;
    //echo "<description>".$val->media:description."</description>".PHP_EOL;
    //echo "<views>".$val->media:statistics["views"]."</views>".PHP_EOL;
    echo "<pubDate>".$val->published."</pubDate>".PHP_EOL;
    echo "</item>".PHP_EOL;
}

How can I get the values of these tags without setting up namespaces. doing a var_dump on $xml->entry doesn't even show the namespaced elements. Is there a better, built in function for converting XML into arrays?


Solution

  • Got my answer from the code provided by IMSoP. The PHP snippet I ended up using was adapted from aforementioned link, using XML similar to that of the OP:

    foreach ($xml->children(NS_ATOM)->entry as $entry) {
        echo "<item>".PHP_EOL;
        echo "<title>".$entry->title."</title>".PHP_EOL;
        echo "<link>".$entry->link->attributes(null)->href."</link>".PHP_EOL;
        echo "<image>".$entry->children(NS_MEDIA)->group->children(NS_MEDIA)->thumbnail->attributes(null)->url."</image>".PHP_EOL;
        echo "<description>".$entry->children(NS_MEDIA)->group->children(NS_MEDIA)->description."</description>".PHP_EOL;
        echo "<guid>".$entry->children(NS_YT)->videoId."</guid>".PHP_EOL;
        echo "<views>".$entry->children(NS_MEDIA)->group->children(NS_MEDIA)->community->children(NS_MEDIA)->statistics->attributes(null)->views."</views>".PHP_EOL;
        echo "<pubDate>".$entry->published."</pubDate>".PHP_EOL;
        echo "</item>".PHP_EOL;
    }
    

    Hope this can help somebody in the future. It was the easiest example of XML namespace parsing I've come across so far.