Ich habe eine Weile gegooglet und getüftelt bis es ging, jetzt geht es:
Ich habe eine kleine Klasse geschrieben(kommt auch im FW zum Einsatz), die mir PHP-Arrays in konformes XML und zurück umwandelt, eigentlich wollte ich ja das schöne WDDX verwenden, aber meine Webhoster mag nicht so wie ich, PHP Serialize kommt nicht in Frage, das selbe trifft auf json zu, außerdem will man den spass ja vlt auch irgendwohin mal exportieren und da ist XML schon schöner, irgendwie. Die PEAR Pakete wollte ich für so ein kleinens Problem auch nicht nutzen, ansonsten wäre der PEAR::XML_Serializer eine sehr schöne Sache gewesen.
Sie hat leider ein paar kleine Kinderkrankheiten, z.B. das leere Elemente rausfallen, darum fülle ich leere Elemente mit einem festgelegten Füllzeichen vorher auf um das Problem zu umgehen, ja ich weis das ist doof, ach machts doch selbst besser :D.
Genug gefaselt, hier die Klasse:
/** (c) 2010 Arne "w13531" Wenzel [ mailto: w13531 (at) terrorhippiecrew (dot) net ] **/
class LIB_Model_XMLFile extends FW_Model_File {
private $file = null;
public function __construct($file = null) {
$this->file = $file;
}
/**
* reads a XML File to an array
* @param $file
* @return array()
**/
public function XMLFile2array($file = null) {
if($file == null) {
$file = $this->file;
}
if(file_exists($file)) {
$xml = simplexml_load_file($file);
$xml = $this->xml2array($xml);
array_walk_recursive($xml, array($this, 'remove_'));
return $xml;
}
return $file;
}
private function remove_(&$value, $key) {
if($value == '_') {
$value = '';
}
$value = html_entity_decode($value, ENT_QUOTES, 'UTF-8');
}
/**
* iterates over an SimpleXML object to convert it into an array
**/
private function xml2array($data) {
if (is_object($data)) {
$data = get_object_vars($data);
}
return (is_array($data)) ? array_map(array($this, 'xml2array'), $data) : $data;
}
/**
* converts a array into an xml file
**/
public function array2XMLFile(array $array, $file = null) {
if($file == null) {
$file = $this->file;
}
if(file_exists($file)) {
array_walk_recursive($array, array($this, 'add_'));
$xml = $this->array2xml($array, 'page');
//pretty output
/*$doc = new DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;
$domnode = dom_import_simplexml($xml);
$domnode = $doc->importNode($domnode, true);
$domnode = $doc->appendChild($domnode);
return $doc->saveXML();*/
return $xml->asXML($file);
}
return $file;
}
private function add_(&$value, $key) {
if($value == '' || empty($value)) {
$value = '_';
}
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
}
/**
* iterates over an array to convert it into xml
* @param $data: array
* @param $rootNodeName
* @param $xml SimplXMLElement
* @return $xml SimplXMLElement
**/
private function array2xml($data, $rootNodeName = 'data', &$xml = null) {
if (is_null($xml)) {
$xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE html_ent [
<!ENTITY auml "ä">
<!ENTITY Auml "Ä">
<!ENTITY uuml "ü">
<!ENTITY Uuml "Ü">
<!ENTITY ouml "ö">
<!ENTITY Ouml "Ö">
<!ENTITY nbsp " ">
<!ENTITY euro "€">
<!ENTITY quot """>
<!ENTITY apos "'">
<!ENTITY szlig "ß">
<!ENTITY amp "&">
]>';
$xml = simplexml_load_string($xml . "<$rootNodeName />");
}
foreach($data as $key => $value) {
if(is_numeric($key)) {
$key = $rootNodeName;
}
$key = preg_replace('/[^a-z0-9\-\_\.\:]/i', '', $key);
if(is_array($value)) {
$node = $this->isAssoc($value) ? $xml->addChild($key) : $xml;
$this->array2xml($value, $key, $node);
} else {
$xml->addChild($key, $value);
}
}
return $xml;
}
private function isAssoc( $array ) {
return (is_array($array) && 0 !== count(array_diff_key($array, array_keys(array_keys($array)))));
}
}