<?php

if (version_compare(PHP_VERSION,'5','>='))
{
 	require_once('domxml-php4-to-php5.php');
}

class Xml2Array
{
	var $xml;
	var $array;
	var $error;
	
	function Xml2array($xml = null)
	{
		$this->array = array();
		$this->error = "";
		
		$this->setXml($xml);
	}
	
	function setXml($xml)
	{
		$this->xml = empty($xml) ? "" : ereg_replace(">[ \r\n]+<", "><", trim($xml));
	}
	
	function getXml()
	{
		return $this->xml;
	}
	
	function getArray()
	{
		return $this->array;
	}
	
	function getError()
	{
		return empty($this->error) ? false : $this->error;
	}
	
	function decode($str)
	{
		return iconv("utf-8", "windows-1251", $str);
	}
	
	function parse()
	{
		$this->array = array();
		$this->error = "";
		
		if(!$this->xml)
		{
			return true; 
		}
		
		if(!$xmlDoc = domxml_open_mem($this->xml, DOMXML_LOAD_PARSING, &$errors))
		{
			
			$errorsString = "";

			foreach($errors as $error)
			{
				foreach ($error as $key=>$str)
				{
					$errorsString .= $key . " => " . $str . "; ";
				}

				$errorsString .= "<br />\n";
			}

			$this->error = "Невозможно загрузить документ из файла: <br />\n" . $errorsString;
			return false;
		}
		
		$rootElement = $xmlDoc->document_element();
		
		if($rootElement)
		{
			$this->array["root"] = $rootElement->tagname();
		}
		else 
		{
			$this->error = "Нет корневого элемента!";
			return false;
		}
		
		if(!$this->parseNode($rootElement, $this->array))
		{
			return false;
		}
		else 
		{
			return true;
		}
	}
	
	// Recursive
	function parseNode($xmlNode, &$array)
	{
		if(method_exists($xmlNode, "attributes"))
		{
			$attributes = $xmlNode->attributes();
			
			if(is_array($attributes) && !empty($attributes))
			{
				$array["attributes"] = array();
				
				foreach($attributes as $attribute)
				{
					$array["attributes"][$attribute->name] = $this->decode($attribute->value);
				}
			}
		}
		
		if($xmlNode->has_child_nodes())
		{
			foreach($xmlNode->child_nodes() as $childNode)
			{
				if($childNode->node_type() == XML_ELEMENT_NODE)
				{
					$tagname = $childNode->tagname();					
					
					if(is_string($array))
					{
						$text = $array;
						$array = array();

						$array["text"] = $this->decode($text);					
					}
					
					if(is_array($array) && !isset($array[$tagname]))
					{
						$array[$tagname] = array();										
						$this->parseNode($childNode, $array[$tagname]);
					}
					elseif(is_array($array) && (!isset($array[$tagname][0]) || is_string($array[$tagname]))) 
					{
						$first = $array[$tagname];
						$array[$tagname] = array();
						$array[$tagname][0] = $first;
						
						$array[$tagname][1] = array();
						$this->parseNode($childNode, $array[$tagname][1]);
					}
					else 
					{
						$array[$tagname][count($array[$tagname])] = array();
						$this->parseNode($childNode, $array[$tagname][count($array[$tagname]) - 1]);
					}
				}
				else 
				{
					if(method_exists($childNode, "get_content"))
					{
						$content = $childNode->get_content();
					}
					else 
					{
						$content = "";
					}
					
					if(is_array($array))
					{
						if(empty($array))
						{
							$array = $this->decode($content);
						}
						else 
						{
							if(isset($array["text"]))
							{
								$array["text"] .= $this->decode($content);
							}
							else 
							{
								$array["text"] = $this->decode($content);
							}
						}
					}
					else 
					{
						$array .= $this->decode($content);
					}
				}
			}
		}
		
		return $array;
	}
}

?>