Converting XML to an array using PHP

December 27th 2012

As you know, I integrate with a large number of Payment Providers. For some reason, they've been left in 1995 and feel that XML is the best thing since sliced bread. Converting XML to an array isn't easy. But if you convert it, then it's a lot easier to use.

As you an I both know, this isn't the best way of doing things. After years of playing around with the DOMDocument, I created this class to convert an XML string to a well formatted PHP Array.

So here's my class to convert XML to an array in PHP.

PHP Code:
<?php
class App_Convert_XmlToArray {

    const 
NAME_ATTRIBUTES '@attributes';

    const 
NAME_CONTENT '@content';

    const 
NAME_ROOT '@root';

    
/**
     * Convert a given XML String to Array
     *
     * @param string $xmlString
     * @return array|boolean false for failure
     */
    
public static function XmlToArray($xmlString) {
        
$doc = new DOMDocument();
        
$load $doc->loadXML($xmlString);
        if (
$load == false) {
            return 
false;
        }
        
$root $doc->documentElement;
        
$output self::DOMDocumentToArray($root);
        
$output[self::NAME_ROOT] = $root->tagName;
        return 
$output;
    }

    
/**
     * Convert DOMDocument->documentElement to array
     *
     * @param DOMElement $documentElement
     * @return array
     */
    
protected static function DOMDocumentToArray($documentElement) {
        
$return = array();
        switch (
$documentElement->nodeType) {

            case 
XML_CDATA_SECTION_NODE:
                
$return trim($documentElement->textContent);
                break;
            case 
XML_TEXT_NODE:
                
$return trim($documentElement->textContent);
                break;

            case 
XML_ELEMENT_NODE:
                for (
$count=0$childNodeLength=$documentElement->childNodes->length$count<$childNodeLength$count++) {
                    
$child $documentElement->childNodes->item($count);
                    
$childValue self::DOMDocumentToArray($child);
                    if(isset(
$child->tagName)) {
                        
$tagName $child->tagName;
                        if(!isset(
$return[$tagName])) {
                            
$return[$tagName] = array();
                        }
                        
$return[$tagName][] = $childValue;
                    }
                    elseif(
$childValue || $childValue === '0') {
                        
$return = (string) $childValue;
                    }
                }
                if(
$documentElement->attributes->length && !is_array($return)) {
                    
$return = array(self::NAME_CONTENT=>$return);
                }

                if(
is_array($return))
                {
                    if(
$documentElement->attributes->length)
                    {
                        
$attributes = array();
                        foreach(
$documentElement->attributes as $attrName => $attrNode)
                        {
                            
$attributes[$attrName] = (string) $attrNode->value;
                        }
                        
$return[self::NAME_ATTRIBUTES] = $attributes;
                    }
                    foreach (
$return as $key => $value)
                    {
                        if(
is_array($value) && count($value)==&& $key!=self::NAME_ATTRIBUTES)
                        {
                            
$return[$key] = $value[0];
                        }
                    }
                }
                break;
        }
        return 
$return;
    }

}

Using the class to convert XML to a PHP array is pretty straightforward. You can do it like this:

PHP Code:
<?php
// first, get your XML string ready.
$x '<?xml version="1.0"?>
...
...'
;
$array App_Convert_XmlToArray::XmlToArray($x);
var_dump($array);