<?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));
}
}
}
?>