Adsar Logo


XML to Arrays in PHP



A lot of the work that I do entails reading in datafeeds, transforming the data, and loading it into databases.

There's a great function that I use all the time to help read in XML data and convert it to PHP arrays:

function xml2array($xml, $flattenValues=true, $flattenAttributes = true, $flattenChildren=true, $valueKey='@value', $attributesKey='@attributes', $childrenKey='@children') {

    $return = array();
    if (!($xml instanceof SimpleXMLElement)) {
        return $return;
    }
    $name = $xml->getName();
    $_value = trim((string) $xml);
    if (strlen($_value) == 0) {
        $_value = null;
    };

    if ($_value !== null) {
        if (!$flattenValues) {
            $return[$valueKey] = $_value;
        } else {
            $return = $_value;
        }
    }

    $children = array();
    $first = true;
    foreach ($xml->children() as $elementName => $child) {
        $value = xml2array($child, $flattenValues, $flattenAttributes, $flattenChildren, $valueKey, $attributesKey, $childrenKey);
        
        if (isset($children[$elementName])) {
            if ($first) {
                $temp = $children[$elementName];
                unset($children[$elementName]);
                $children[] = $temp;

                $first = false;
            }
            $children[] = $value;
        } else {
            $children[$elementName] = $value;
        }
    }
    if (count($children) > 0) {
        if (!$flattenChildren) {
            $return[$childrenKey] = $children;
        } else {
            if (is_array($return)) $return = array_merge($return, $children);
            else $return = array($return => $children);
        }
    }

    $attributes = array();
    foreach ($xml->attributes() as $name => $value) {
        $attributes[$name] = trim($value);
    }
    if (count($attributes) > 0) {
        if (!$flattenAttributes) {
            $return[$attributesKey] = $attributes;
        } else {
            if (is_array($return)) $return = array_merge($return, $attributes);
            else $return = array($return => $attributes);
        }
    }

    if (is_countable($return) && count($return) === 0) {
        return null; //will return null instead of an empty array
    }

    return $return;
}

Adapted from https://gist.github.com/yeroon/925483 and improved for PHP 8



Trees for life


Want to get in touch? mail@adsar.co.uk