Parsing XML with PHP5

Recently, I had cause to re-visit some old code I had lying around. The code in question is designed to extract data from the administrative XML interface to a SHOUTcast radio station and display the latest track listings. The code in question was written in PHP4 using the core PHP parsing functions.

That API set is pretty horrible. Essentially, you set a couple of call back functions for starting tags, ending tags and tag content etc, then you have to have a huge if statement and use global variables to co-ordinate which tag you’re looking at. I decided that piece of code needed a 100% re-write, in PHP5 using the DOM Document API. i.e. do it the proper way. They way I would in any other language.

Unfortunately, the php.net documentation is a little wrong. Or out of date. The documents seem to be relevant for PHP4.3 only. Which results in lots of errors when you write code referencing the documents. So, without further rambling, here’s a quick rule which appears to help:

Where the documentation states function_name() instead, use an attribute functionName. In fact.

This is not true of all things. Some things are still functions, and I think they are mostly functionName() instead of the documented function_name.

Look at the documentation for any DOM XML components from other vendors, such as the Microsoft XML 4.0 object, it seems PHP’s methods match that.

So, here’s what I came up with using the manual:

$values = array();
$dom = new DOMDocument();
$dom->loadXML($xml);
$nodes = $dom->document_element()->first_child()->child_nodes();
foreach($nodes as $node) {
    $childNodes = $node->child_nodes();
    $value = $childNodes[1]->node_value();
    $values[] = $value;
}

Which of course is all-sorts of not working. The correct version is in fact:

$values = array();
$dom = new DOMDocument();
$dom->loadXML($xml);
$nodes = $dom->documentElement->firstChild->childNodes;
foreach($nodes as $node) {
    $childNodes = $node->childNodes;
    $value = $childNodes->item(1)->nodeValue;
    $values[] = $value;
}

I hope this saves at least one person a few lost minutes.

Popularity: 40% [?]

Leave a Reply