<?PHP

/**
* generates or reads xml data
*/
class Xml  {

	var $XMLData = array();
	/**
	* get xml data from file or string
	* @param String $xmlfile AS filename with full location
	* @param String $xmldata='' AS xml string
	* @param Boolean $convertintoarray=true 
	* @return xml data
	*/
	function getXmlData($xmlfile, $xmldata='', $convertintoarray=true){

		$this->convertintoarray = $convertintoarray;
		$this->is_xml_file = $xmlfile ? true : false;
		unset($this->XMLData);
		return $this->cdata($xmlfile ? $xmlfile : $xmldata);
    }

	private function convertXmlNode($object, $attrarray){

		$attrarray = array();
		if($object->attributes()){

		   foreach($object->attributes() as $ak => $av) {

				$attrarray[$ak] = (string)$av;
		   }
		   $newvalue['@attributes'] = $attrarray;
	   }

		foreach($object as $key => $value){

			 if($object->$key->children()) {

				$newvalue[$key] = $object->$key->attributes() ? $this->getXMLnode($object->$key->children(), array('@attributes' => $attrarray)) : $this->getXMLnode($object->$key->children(), $param);
			 }
			 else{

				$newvalue[$key] = (string)$value;
			 }
		}
		return $newvalue;
	}

	private function getXMLnode($object, $array=array()) {

		foreach($object as $key => $value) {

			$attrarray = array();
			if($object->$key->attributes()){

			   foreach($object->$key->attributes() as $ak => $av) {

					$attrarray[$ak] = (string)$av;
			   }
		   }

		   if($object->$key->children()){

			   if(count($object->$key) > 1){

					$array[$key][] = $this->convertXmlNode($value, $attrarray);
			   }
			   else{

				   $array[$key] = $object->$key->attributes() ? $this->getXMLnode($object->$key->children(), array('@attributes' => $attrarray)) : $this->getXMLnode($object->$key->children(), $param);
			   }
		   }
		   else{

			   $array[$key] = $object->$key->attributes() ? array('@attributes' => $attrarray) : (string)$value;
		   }
       }
	   return $array;
	}

	private function cdata($xmlfile_or_data){

		$xse = new SimpleXMLElement($xmlfile_or_data, NULL, $this->is_xml_file);
		if($this->convertintoarray == true){

			if($xse->attributes()){

				 foreach($xse->attributes() as $ak => $av) {

						$attrarray[$ak] = (string)$av;
				 }
				 $array['@attributes'] = $attrarray;

				 $array = $this->getXMLnode($xse, $array);
				 $arr = array($xse->getName() => $array );
		   }
		   else{

			   $arr = array($xse->getName() => $this->getXMLnode($xse)) ;
		   }
		   return $arr;
		}
		else{

		   $tmpxse = array($xse->getName() => $xse);

			return $tmpxse;
		}
	}

	/**
	* create xml from array
	* @param $data_array['list'] = 'val1';
	* @param $data_array['list']['item']['@attributes'] = array('id' => 1);
	* @param $data_array['list']['item']['name'] = 'company name';
	* @param $data_array['list']['item']['phone'] = '123';
	* @param $data_array['list']['type'] = 'company';
	* @param String $encoding='UTF-8'
	* @return xml string
	*/
	function create_xml($data_array, $encoding='UTF-8'){

		$first_key = array_keys($data_array);
		$xml = $this->construct_data($data_array, 0, '', $data_array);
		return '<?xml version="1.0" encoding="'.$encoding.'"?>'."\n".$xml;
	}

	private function construct_data($data_array, $level, $last_key, $last_data_array){

		foreach($data_array as $k => $v){

			if(!is_array($v)){

				$xml.= str_repeat('	', $level).'<'.$k.'>'.$v.'</'.$k.'>'."\n";
			}
			if(is_array($v)){

				$attributes = '';

				if($v['@attributes']){

					$attributes = $this->get_attributes($v['@attributes']);
					unset($v['@attributes']);
				}

				if(is_numeric($k)){

					$this->numeric_data_i[$last_key] = $k;
					$last_data_array_keys = array_keys($last_data_array[$last_key]);

					if($this->numeric_data_i[$last_key] == $last_data_array_keys[count($last_data_array_keys)-1]){

						$xml .= $this->construct_data($v, $level, $last_key, $data_array);
					}
					else{

						$xml .= $this->construct_data($v, $level, $last_key, $data_array).str_repeat('	', ($level-1)).'</'.$last_key.'>'."\n".str_repeat('	', ($level-1)).'<'.$last_key.$attributes.'>'."\n";
					}
				}
				else{

					$level ++;

					$xml .= str_repeat('	', ($level-1)).'<'.$k.$attributes.'>'."\n".$this->construct_data($v, $level, $k, $data_array).str_repeat('	', ($level-1)).'</'.$k.'>'."\n";
					$level --;
				}
			}
		}
		return $xml;
	}

	private function get_attributes($attributes_array){

		$attributes = '';

		if(is_array($attributes_array)){

			foreach($attributes_array as $k => $v){

				$attributes .= ' '.$k.'="'.$v.'"';
			}
		}

		return $attributes;
	}
}

?>