Job Folkers Job Folkers - 5 months ago 32
PHP Question

Build an array as a tree structure from an XML file

I am trying to read this xml file, but the code I am trying to make should work for any xml-file:

<?xml version="1.0"?>

I am using the two functions below to turn the XML-file into an array and turn that array into a tree.

I am trying to keep the parent-child relationship of the XML file. All I am getting back from the second function is an array with all the tags in the xml-file.

Can someone please help me?

function build_xml_tree(array $vals, $parent, $level) {
$branch = array();

foreach ($vals as $item) {
if (($item['type'] == "open") || $item['type'] == "complete") {
if ($branch && level == $item['level']) {
array_push($branch, ucfirst(strtolower($item['tag'])));
} else if ($parent == "" || $level < $item['level']) {
$branch = array(ucfirst(strtolower($item['tag'])) => build_xml_tree($vals, strtolower($item['tag']), $level));
return $branch;

function build_tree ($begin_tree, $content_naam) {
$xml = file_get_contents('xml_files/' . $content_naam . '.xml');
$p = xml_parser_create();
xml_parse_into_struct($p, $xml, $vals, $index);


$eindarray = array_merge($begin_tree, build_xml_tree($vals, "", 1));

return $eindarray;


There are many classes which can load an XML file. Many of them already represent the file in a tree structure: DOMDocument is one of them.

It seems a bit strange that you want to make a tree as an array when you already have a tree in a DOMDocument object: since you'll have to traverse the array-tree in some way... why don't you traverse directly the tree structure of the object-tree for printing for example?

Anyway the following code should do what you're asking for: I've used a recursive function in which the array-tree is passed by reference. It should be trivial at this point to arrange my code to better suit your needs - i.e. complete the switch statement with more case blocks.

  • the $tree array has a numeric key for each node level
  • the tag node names are string values
  • if an array follows a string value, it contains the node's children
  • any potential text node is threated as a child node

function buildTree(DOMNode $node = NULL, &$tree) {

    foreach ($node->childNodes as $cnode) {

        switch($cnode->nodeType) {
            case XML_ELEMENT_NODE:
                $tree[] = $cnode->nodeName;
            case XML_TEXT_NODE:
                $tree[] = $cnode->nodeValue;

        if ($cnode->hasChildNodes())
            buildTree($cnode, $tree[count($tree)]);

$source ='the string which contains the XML';

$doc = new DOMDocument();
$doc->preserveWhiteSpace = FALSE;
$doc->loadXML($source, LIBXML_NOWARNING);

$tree = array();
buildTree($doc, $tree);