Location: PHPKode > scripts > XmlArray > xmlarray/class_XmlArray.php
<?php
/**
 * This is just a collection of functions found on web, either in the user comments of the online PHP manual, 
 * or in other places.Some functions were modified.
 * The class purpose is to convert an xml into a multidimensional associative 
 * array, and vice versa (a well structured array into a xml). It uses the SimpleXml library. For the moment it 
 * can't handle attributs, and tests were made only using simple xml structures
 * 
 * @author All the people who contributed on the WWW with the code found in this class
 * @contact sebastianvasile [@] yahoo.com
 */
class XmlArray{
	
	/**
	 * SimpleXml object
	 * @var SimpleXml
	 */
	private $xmlObject;
		
	/**
	 * Default root node name
	 *
	 * @var string
	 */
	private $name = "config";
	
	/**
	 * Empty constructor
	 *
	 */
	function __construct(){}
	
	/**
	 * Set the xml source, either a file or a string containing the xml 
	 *
	 * @param string $mixed_string
	 */
	public function set_xml($mixed_string) {
		//we received a file as the xml source
		if (file_exists($mixed_string)){
			$this->xmlObject = simplexml_load_file($mixed_string);
		} else {
			
			//we received a string with the xml data
			$this->xmlObject = simplexml_load_string($mixed_string); 
		}
	}
	
		
	/**
	 * Set the name for the root tag
	 *
	 * @param string $param
	 */
	public function set_name($param){
		$this->name = $param;
	}
	
	
	
	/**
	 * Get the current root node name
	 *
	 * @return string 
	 */
	public function get_name(){
		return $this->name;
	}
	
	
	
	/**
	 * Get the multi-dimensional associative array, from the current xml
	 *
	 * @param SimpleXml $object
	 * @return array
	 */
	public function xml2array($object = "") {
		if ($object == ""){
			$object	= $this->xmlObject;
		}
		$return = NULL;	     
		if(is_array($object)) {
			foreach($object as $key => $value)
				$return[$key] = $this->xml2array($value);
		} else {
			$var = get_object_vars($object);
		
			if($var) {
				foreach($var as $key => $value)
					$return[$key] = $this->xml2array($value);
			} else {
				return strval($object);
			}
		}	
		return $return;
	}
	
	
	
	/**
	 * Get the xml string starting from a well formed muti-dimensional array
	 *
	 * @param array $array
	 * @param string $name
	 * @param SimpleXml $xml
	 * @return string
	 */
	public function array2xml($array = array(), $name= "", &$xml=null ) {
		
		if (count($array) == 0){
			$array = $this->xmlArray;
		}
		if (trim($name) == ""){
			$name = $this->name;
		}
		
		if (version_compare(phpversion(), "5.1.3") >= 0){
			
			if(is_null($xml)) {
		        $xml = new SimpleXMLElement("<{$name}/>\n");
		    }
			
		    foreach($array as $key => $value) {	    	
				$counter = 0;	    	
		        if ( is_array($value) && $this->isNumericArray($value) ) {
	
		        	if ($this->getDeepLevelOfArray($value) > 1){
		        		foreach ($value as $k => $v) {
		        			$xml->addChild($key);
		            		$current_node = $xml->$key;
		        			$this->array2xml($v, $name, $current_node[$counter]);
		            		$counter++;
		        		}
		        	} elseif ($this->getDeepLevelOfArray($value) == 1) {
		        		foreach ($value as $k => $v) {
							$xml->addChild($key, $v);
						}
		        	}
	
		        } elseif (is_array($value) && !$this->isNumericArray($value)) {
					
		        	if ($this->getDeepLevelOfArray($value) > 1){
		        		$xml->addChild($key);
		            	$this->array2xml($value, $name, $xml->$key);
		        	} elseif ($this->getDeepLevelOfArray($value) == 1) {
		        		$xml->addChild($key);
		        		$this->array2xml($value, $name, $xml->$key);
		        	}
	
		    	} else {
		    		$xml->addChild($key, $value);
		        }
		    }
		    return ($xml->asXML());
	
	    } else {
	    	//PHP version older than 5.1.3
	    	if(is_null($xml)) {
		        $xml = new SimpleXMLElement("<{$name}/>\n");
		    }
			
		    foreach($array as $key => $value) {	    	
				$counter = 0;	    	
		        if ( is_array($value) && $this->isNumericArray($value) ) {
	
		        	if ($this->getDeepLevelOfArray($value) > 1){
		        		foreach ($value as $k => $v) {
		        			$this->addChildOld($xml, $key);
		            		$current_node = $xml->$key;
		        			$this->array2xml($v, $name, $current_node[$counter]);
		            		$counter++;
		        		}
		        	} elseif ($this->getDeepLevelOfArray($value) == 1) {
		        		foreach ($value as $k => $v) {
							$this->addChildOld($xml, $key, $v);
						}
		        	}
	
		        } elseif (is_array($value) && !$this->isNumericArray($value)) {
					
		        	if ($this->getDeepLevelOfArray($value) > 1){
		        		$this->addChildOld($xml, $key);
		            	$this->array2xml($value, $name, $xml->$key);
		        	} elseif ($this->getDeepLevelOfArray($value) == 1) {
		        		$this->addChildOld($xml, $key);
		        		$this->array2xml($value, $name, $xml->$key);
		        	}
	
		    	} else {
		    		$this->addChildOld($xml, $key, $value);
		        }
		    }
		    return ($xml->asXML());
	    }
	}

	/**
	 * Function found on Web (PHP Manual)
	 *
	 * @param SimeplXml $parent
	 * @param string $name
	 * @param string $value
	 */
	private function addChildOld($parent, $name, $value=''){
	    $new_child = new SimpleXMLElement("<$name>$value</$name>");
	    $node1 = dom_import_simplexml($parent);
	    $dom_sxe = dom_import_simplexml($new_child);
	    $node2 = $node1->ownerDocument->importNode($dom_sxe, true);
	    $node1->appendChild($node2);
	    return simplexml_import_dom($node2);
	}
	
	
	/**
	 * Function found on web, checks if a given array is numeric
	 * 
	 * @param array $ar
	 * @return boolean
	 */
	private function isNumericArray($ar) {
		if (is_array($ar)) {
			$keys = array_keys($ar);
			natsort($keys); //String keys will be last
			return is_int(array_pop($keys));
		} else {
			return false;
		}
	}
	
	/**
	 * Gets the deepest level of an array, by recursive walking it.
	 *
	 * @param array $array
	 * @param int $current_deep
	 * @param int $deepest_level
	 * @return int
	 */
	private function getDeepLevelOfArray(&$array, $current_deep = 0, $deepest_level = 0) {
		if (is_array($array)){
			$current_deep++;
			if ($deepest_level < $current_deep){
				$deepest_level = $current_deep;
			}
			foreach ($array as $key=>$value){
				if (is_array($value)){
					$temp 			= $this->getDeepLevelOfArray($value, $current_deep, $deepest_level);
					$current_deep 	= $temp['current_deep'];
					$deepest_level 	= $temp['deepest_level'];
				}
			}
		}
		
		if ($current_deep <= 1){
			return $deepest_level;
		} else {
			return (array("current_deep" => --$current_deep, "deepest_level" => $deepest_level));
		}
	}
	
}
?>
Return current item: XmlArray