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

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