Australia's Leading Digital Marketing Experts. T. 1300 235 433  |  Aggregation Enquires Welcome

Convert XML Files With Nested Attributes and Child Nodes To Array With PHP

The function we provided in our last article that converted an XML file to a PHP array didn't support attributes and child nodes. This function, authored by Adrien (aka Gaarf), will build a nice array with all relevant nested data supported. It's slow, but it performs as advertised.

1
<?php 
2
/**
3
  * convert xml string to php array - useful to get a serializable value
4
  *
5
  * @param string $xmlstr
6
  * @return array
7
*/
8
 
9
function xmlstr_to_array($xmlstr) {
10
  $doc = new DOMDocument();
11
  $doc->loadXML($xmlstr);
12
  $root = $doc->documentElement;
13
  $output = domnode_to_array($root);
14
  $output['@root'] = $root->tagName;
15
  return $output;
16
}
17
function domnode_to_array($node) {
18
  $output = array();
19
  switch ($node->nodeType) {
20
    case XML_CDATA_SECTION_NODE:
21
    case XML_TEXT_NODE:
22
      $output = trim($node->textContent);
23
    break;
24
    case XML_ELEMENT_NODE:
25
      for ($i=0, $m=$node->childNodes->length; $i<$m; $i++) {
26
        $child = $node->childNodes->item($i);
27
        $v = domnode_to_array($child);
28
        if(isset($child->tagName)) {
29
          $t = $child->tagName;
30
          if(!isset($output[$t])) {
31
            $output[$t] = array();
32
          }
33
          $output[$t][] = $v;
34
        }
35
        elseif($v || $v === '0') {
36
          $output = (string) $v;
37
        }
38
      }
39
      if($node->attributes->length && !is_array($output)) { //Has attributes but isn't an array
40
        $output = array('@content'=>$output); //Change output into an array.
41
      }
42
      if(is_array($output)) {
43
        if($node->attributes->length) {
44
          $a = array();
45
          foreach($node->attributes as $attrName => $attrNode) {
46
            $a[$attrName] = (string) $attrNode->value;
47
          }
48
          $output['@attributes'] = $a;
49
        }
50
        foreach ($output as $t => $v) {
51
          if(is_array($v) && count($v)==1 && $t!='@attributes') {
52
            $output[$t] = $v[0];
53
          }
54
        }
55
      }
56
    break;
57
  }
58
  return $output;
59
}

Usage is easy.

1
$array = xmlstr_to_array($xml);
2
echo print_r($array, true);

Like this article?

Share on facebook
Share on Facebook
Share on twitter
Share on Twitter
Share on linkedin
Share on Linkdin
Share on pinterest
Share on Pinterest

Leave a comment