Convert XML to array

<?php
/**
 * Converts XML to array
 *
 * @param unknown_type $url
 * @param unknown_type $get_attributes
 * @param unknown_type $priority
 * @return unknown
 */
function xml2array($url, $get_attributes = 1, $priority = 'tag')
{
   
$contents = "";
    if (!
function_exists('xml_parser_create'))
    {
        return array ();
    }
   
$parser = xml_parser_create('');
    if (!(
$fp = @ fopen($url, 'rb')))
    {
        return array ();
    }
    while (!
feof($fp))
    {
       
$contents .= fread($fp, 8192);
    }
   
fclose($fp);
   
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
   
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
   
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
   
xml_parse_into_struct($parser, trim($contents), $xml_values);
   
xml_parser_free($parser);
    if (!
$xml_values)
        return;
//Hmm...
   
$xml_array = array ();
   
$parents = array ();
   
$opened_tags = array ();
   
$arr = array ();
   
$current = & $xml_array;
   
$repeated_tag_index = array ();
    foreach (
$xml_values as $data)
    {
        unset (
$attributes, $value);
       
extract($data);
       
$result = array ();
       
$attributes_data = array ();
        if (isset (
$value))
        {
            if (
$priority == 'tag')
               
$result = $value;
            else
               
$result['value'] = $value;
        }
        if (isset (
$attributes) and $get_attributes)
        {
            foreach (
$attributes as $attr => $val)
            {
                if (
$priority == 'tag')
                   
$attributes_data[$attr] = $val;
                else
                   
$result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
           
}
        }
        if (
$type == "open")
        {
           
$parent[$level -1] = & $current;
            if (!
is_array($current) or (!in_array($tag, array_keys($current))))
            {
               
$current[$tag] = $result;
                if (
$attributes_data)
                   
$current[$tag . '_attr'] = $attributes_data;
               
$repeated_tag_index[$tag . '_' . $level] = 1;
               
$current = & $current[$tag];
            }
            else
            {
                if (isset (
$current[$tag][0]))
                {
                   
$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
                   
$repeated_tag_index[$tag . '_' . $level]++;
                }
                else
                {
                   
$current[$tag] = array (
                       
$current[$tag],
                       
$result
                   
);
                   
$repeated_tag_index[$tag . '_' . $level] = 2;
                    if (isset (
$current[$tag . '_attr']))
                    {
                       
$current[$tag]['0_attr'] = $current[$tag . '_attr'];
                        unset (
$current[$tag . '_attr']);
                    }
                }
               
$last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
               
$current = & $current[$tag][$last_item_index];
            }
        }
        elseif (
$type == "complete")
        {
            if (!isset (
$current[$tag]))
            {
               
$current[$tag] = $result;
               
$repeated_tag_index[$tag . '_' . $level] = 1;
                if (
$priority == 'tag' and $attributes_data)
                   
$current[$tag . '_attr'] = $attributes_data;
            }
            else
            {
                if (isset (
$current[$tag][0]) and is_array($current[$tag]))
                {
                   
$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
                    if (
$priority == 'tag' and $get_attributes and $attributes_data)
                    {
                       
$current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
                    }
                   
$repeated_tag_index[$tag . '_' . $level]++;
                }
                else
                {
                   
$current[$tag] = array (
                       
$current[$tag],
                       
$result
                   
);
                   
$repeated_tag_index[$tag . '_' . $level] = 1;
                    if (
$priority == 'tag' and $get_attributes)
                    {
                        if (isset (
$current[$tag . '_attr']))
                        {
                           
$current[$tag]['0_attr'] = $current[$tag . '_attr'];
                            unset (
$current[$tag . '_attr']);
                        }
                        if (
$attributes_data)
                        {
                           
$current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
                        }
                    }
                   
$repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
               
}
            }
        }
        elseif (
$type == 'close')
        {
           
$current = & $parent[$level -1];
        }
    }
    return (
$xml_array);
}
?>

<?php

function xmlstr_to_array($xmlstr) {
 
$doc = new DOMDocument();
 
$doc->loadXML($xmlstr);
  return
domnode_to_array($doc->documentElement);
}

function
domnode_to_array($node) {
 
$output = array();
  switch (
$node->nodeType) {

    case
XML_CDATA_SECTION_NODE:
    case
XML_TEXT_NODE:
     
$output = trim($node->textContent);
    break;

    case
XML_ELEMENT_NODE:
      for (
$i=0, $m=$node->childNodes->length; $i<$m; $i++) {
       
$child = $node->childNodes->item($i);
       
$v = domnode_to_array($child);
        if(isset(
$child->tagName)) {
         
$t = $child->tagName;
          if(!isset(
$output[$t])) {
           
$output[$t] = array();
          }
         
$output[$t][] = $v;
        }
        elseif(
$v || $v === '0') {
         
$output = (string) $v;
        }
      }
      if(
$node->attributes->length && !is_array($output)) { //Has attributes but isn't an array
       
$output = array('@content'=>$output); //Change output into an array.
     
}
      if(
is_array($output)) {
        if(
$node->attributes->length) {
         
$a = array();
          foreach(
$node->attributes as $attrName => $attrNode) {
           
$a[$attrName] = (string) $attrNode->value;
          }
         
$output['@attributes'] = $a;
        }
        foreach (
$output as $t => $v) {
          if(
is_array($v) && count($v)==1 && $t!='@attributes') {
           
$output[$t] = $v[0];
          }
        }
      }
    break;
  }
  return
$output;
}
?>

Source: https://github.com/gaarf/XML-string-to-PHP-array/blob/master/xmlstr_to_a...
Knowledge keywords: