I’m sure many php users have needed to read some xml data into a php program and looked around hoping to find a function that can parse an XML file with a few lines of code. The road to simple XML usage may not be that short, but we’ll explore some techniques to get the data you want from an xml source.
First define some xml:

$contents = ‘
<rss version=”2.0″>
<channel>
<item>
<title>Orange Cat</title>
<link>http://www.phpprogrammer.co.uk/</link>
<description>A nice tabby.</description>
</item>
<item>
<title>Black Cat</title>
<link>http://www.phpprogrammer.co.uk/</link>
<description>A shy cat.</description>
</item>
</channel>
</rss>
‘;

Then parse the XML with this PHP code:

$parser = xml_parser_create('UTF-8');
$did_parse = xml_parse_into_struct($parser, trim($contents), $xml_values);
if(!$did_parse) {
	echo xml_error_string(xml_get_error_code($parser)) . " error on line: " . xml_get_current_line_number($parser);
}

The above example takes an “XML document”, in the form of a string, and parses it into an array ($xml_values). The array style and structure is complicated, but we will go through some simple steps to rearrange it into a usable format. $parser is an object. Functions like xml_parse_into_struct($parser … ) take $parser as an argument.

Some error checking is present where it says if(!$did_parse), this isn’t too important for now, but if you load a real file into a string it will help you know what line an invalid XML portion is on if the parsing cannot complete.

Study the way this particular XML rss format works. Usually it starts with rss, and then a channel. I haven’t seen any that use multiple channels so it may not be common, and we will assume 1 for now. Inside the channel, each item has 2 child tags. We will try to organize those items as associative arrays.

$xml_result = array();
$current = &$xml_result;
foreach ($xml_values as $ii) {

	if($ii['type'] == "open") {
		if($ii['tag'] == "RSS") {
			continue;
		}
		$current = &$xml_result[$ii['tag']][];
	} elseif($ii['type'] == "complete") {
		$current[$ii['tag']] = $ii['value'];
	} elseif($ii['type'] == "close") {
		$current = &$xml_result;
	}

}

Adding that code to the end of the previous example will populate the new array, $xml_result, with the data we want from $xml_values and basically ignore anything that we didn’t tell it to pick up. All wee needed to do was loop through $xml_values and put each tag name and value into place depending on it’s type and so on. This code could be expanded to include many things, including attributes, parent child relationships, and so on.

The new array looks like this (using print_r()):

Array
(
    [CHANNEL] => Array
        (
            [0] => Array
                (
                    [TITLE] => Cats
                )

        )

    [ITEM] => Array
        (
            [0] => Array
                (
                    [TITLE] => Orange Cat
                    [LINK] => http://www.phpprogrammer.co.uk/
                    [DESCRIPTION] => A nice tabby.
                )

            [1] => Array
                (
                    [TITLE] => Black Cat
                    [LINK] => http://www.phpprogrammer.co.uk/
                    [DESCRIPTION] => A shy cat.
                )

        )

)

and finally, it is suggested you free the parser object:

xml_parser_free($parser);