I have the following class that I have written. Seems to work OK with simple objects that have one level but does not work well when objects have multiple levels (multi-arrays) and the XML is all messed up. Can anyone help me improve this so it will work with any object?
class XMLGenerator
{
function __construct($obj,$root, $element, $fullXML = true) {
$array = $this->object_2_array($obj);
$this->output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
$this->output .= $this->make($array, $root, $element, $fullXML);
}
//convert objects into arrays
function object_2_array($result){
$array = array();
foreach ($result as $key => $value){
if (is_object($value)){
$array[$key]=XMLGenerator::object_2_array($value);
} elseif (is_array($value)){
$array[$key]=XMLGenerator::object_2_array($value);
} else {
$array[$key]=$value;
}
}
return $array;
}
//make XML
function make($array, $root, $element, $fullXML) {
if (is_numeric($root)) {
$xml = "<{$element}>\n";
} else {
$xml = "<{$root}>\n";
}
foreach ($array as $key => $value) {
if (is_array($value)) {
if ($element == 'options'){ //workaround for orders 3 level problem, need to rethink this - LT
$xml .= $this->make($value, $key, $key, $fullXML);
} else {
$xml .= $this->make($value, $element, $key, $fullXML);
}
} else {
//any fields with HTML need wrapping in CDATA
if (($key === 'Description')||( $key === 'productDescription' )){
$value = '<![CDATA['. $value .']]>';
//remove any chars XML doesnt like
} else {
$value = htmlentities($value,ENT_QUOTES, 'UTF-8');
$value = functions::xml_entities($value);
}
//decide on node name
if (is_numeric($key)) {
$xml .= "<{$root}>{$value}</{$root}>\n";
} else {
$xml .= "<{$key}>{$value}</{$key}>\n";
}
}
}
if (is_numeric($root)) {
$xml .= "</{$element}>\n";
} else {
$xml .= "</{$root}>\n";
}
return $xml;
}
//save XML to file
function saveFile($file){
//create DOM to ensure all XML is valid before writing to file
$doc = new DOMDocument();
$doc->loadXML($this->output);
if ($doc->save("$file")){
return TRUE;
} else {
return FALSE;
}
}
}
The below is a simple object that works well with the above class.
Products Object ( [db_connection:protected] => 3779074 [prod_id:protected] => 0 [shopkeeper:protected] => 0 [fields] => Array (
[productDescription] => Test [productName] => Test [UPC] => 123 ))
The below does not work well at all.
Order Object ( [db_connection:protected] => msSqlConnect Object ( [con] => [dbName] => )
[skID:protected] => 89137 [orderID:protected] => 482325 [order] => Array ( [id] => 482325 [customer] => 491936 [net] => 1565.98 [vat] => 274.05 [billing_address] => Address Object ( [db_connection:protected] => msSqlConnect Object ( [con] => [dbName] => ) [custID:protected] => 491936 [addID:protected] => 156928 [fields] => Array ( [id] => 156928 [surname] => test [forename] => test [add1] => 89 testRoad [add2] => [city] => City [country] => GB [postcode] => POSTCODE ) ) [items] => Array ( [0] => Array ( [id] => 716549 [headerID] => 482325 [productID] => 4084620 [net] => 22.99 [vat] => 4.0233 [qty] => 1 [options] => Array ( [0] => Array ( [id] => [orderDetailsID] => 716549 [optionid] => 763217 [optionCost] => 100 [optionVAT] => 17.5 ) [1] => Array ( [id] => [orderDetailsID] => 716549 [optionid] => 763241 [optionCost] => 10 [optionVAT] => 1.75 ) ) ) [1] => Array ( [id] => 716551 [headerID] => 482325 [productID] => 3779074 [net] => 1400 [vat] => 245 [qty] => 1 [options] => ) ) ) )
Many thanks in advance for any help.