Your problem lies with the fact that you keep building your arrays by creating new arrays, thus creating nested arrays for elements that should be at the same depth.
$arr = array('name' => 'value');
$arr = array($arr, array('name' => 'value'));
$arr = array($arr, array('name' => 'value'));
printf('<pre>%s</pre>', print_r($arr,1));
You should change your else block to something like
else
{
if(is_array($tree) && isset($tree[$xml->name]))
{
$tree[$xml->name][] = ReadNestedAttributedXML($xml);
}
else
{
$tree[$xml->name] = array(ReadNestedAttributedXML($xml));
}
}
But your handling of nodes with attributes seems fishy as well, so I'd suspect you'd need some more work to make things work. I'm at least rather certain that code won't be able to handle any XML document, but it's possible that it may work with yours.
Also, you treat text nodes and cdata sections differently than other nodes. Yes, they are indeed nodes. The cdata sections even have its proper tag. Text nodes however, aren't written by using <text>string literal</text>, but that is how the DOM tree treats them. So in this xml structure
<element>
Some text
<subElement>
Sub text
</subElement>
More text
</element>
<element> contains three child nodes, a text node, a subElement node (which contains one child node, a text node) and another text node. That is, the xml document is actually treated as
<element>
<#text>Some text</#text>
<subElement>
<#text>Sub text</#text>
</subElement>
<#text>More text</#text>
</element>
Now, if you don't treat your text nodes as any other child node, how should you represent the above? Shoud element contain the node value "Some textMore text" or perhaps "Some text More text"?
If you instead treat these as any other child nodes, you'd get the array below, using your current approach where you use the node name of child nodes as array keys
$element['#text'][0] = Some text
$element['#text'][1] = More text
$element['subElement'] = Array
which means you'd still lose information about structure. When you iterate over this array, you are lead to believe that it came from the XML structure
<element>
Some text
More text
<subElement>
Sub text
</subElement>
</element>
which in turn means you'd be better served by keeping child nodes as elements numbered 0 ... N -1, for N child nodes
$element[0] = Array(nodeName => '#text', nodeValue => Some text)
$element[1] = Array(nodeName=>'subElement',0=>Array(nodeName=>'#text', nodeValue=>'Sub text'))
$element[2] = Array(nodeName => '#text', nodeValue => Some text)
But since this means you won't be able to easily iterate over the child Nodes, since each element now contains both child nodes and other stuff like node name and possibly attributes, I'd recommend going to a structure where each element contains
$el['nodeName'] - name of the node, which would be #text for text
$el['attributes'] - array containing this nodes attributes
$el['childNodes'] - integer indexed array of all child nodes
Or for the above example
$element['nodeName'] = 'element';
$element['attributes'] = array();
$element['childNodes'] = array(0 => array('nodeName' => '#text', 'nodeValue' => 'Some text'), 1 => array(nodeName => 'subElement', attributes => array(), childNodes( Array ))
and so on.