135 lines
4.0 KiB
PHP
135 lines
4.0 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* Based on: http://stackoverflow.com/questions/99350/passing-php-associative-arrays-to-and-from-xml
|
||
|
*/
|
||
|
class ArrayToXML
|
||
|
{
|
||
|
private $version;
|
||
|
private $encoding;
|
||
|
|
||
|
/**
|
||
|
* Construct ArrayToXML object with selected version and encoding
|
||
|
*
|
||
|
* for available values check XmlWriter docs http://www.php.net/manual/en/function.xmlwriter-start-document.php
|
||
|
* @param string $xmlVersion XML Version, default 1.0
|
||
|
* @param string $xmlEncoding XML Encoding, default UTF-8
|
||
|
*/
|
||
|
public function __construct($xmlVersion = '1.0', $xmlEncoding = 'UTF-8')
|
||
|
{
|
||
|
$this->version = $xmlVersion;
|
||
|
$this->encoding = $xmlEncoding;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Build an XML Data Set
|
||
|
*
|
||
|
* @param array $data Associative Array containing values to be parsed into an XML Data Set(s)
|
||
|
* @param string $startElement Root Opening Tag, default data
|
||
|
* @return string XML String containing values
|
||
|
* @return mixed Boolean false on failure, string XML result on success
|
||
|
*/
|
||
|
public function buildXML($data, $startElement = 'data')
|
||
|
{
|
||
|
if (!is_array($data)) {
|
||
|
$err = 'Invalid variable type supplied, expected array not found on line ' . __LINE__ . ' in Class: ' . __CLASS__ . ' Method: ' . __METHOD__;
|
||
|
trigger_error($err);
|
||
|
return false; //return false error occurred
|
||
|
}
|
||
|
$xml = new XmlWriter();
|
||
|
$xml->openMemory();
|
||
|
$xml->startDocument($this->version, $this->encoding);
|
||
|
$xml->startElement($startElement);
|
||
|
|
||
|
$data = $this->writeAttr($xml, $data);
|
||
|
$this->writeEl($xml, $data);
|
||
|
|
||
|
$xml->endElement(); //write end element
|
||
|
//returns the XML results
|
||
|
return $xml->outputMemory(true);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Write keys in $data prefixed with @ as XML attributes, if $data is an array.
|
||
|
* When an @ prefixed key is found, a '%' key is expected to indicate the element itself,
|
||
|
* and '#' prefixed key indicates CDATA content
|
||
|
*
|
||
|
* @param XMLWriter $xml object
|
||
|
* @param array $data with attributes filtered out
|
||
|
* @return array $data | $nonAttributes
|
||
|
*/
|
||
|
protected function writeAttr(XMLWriter $xml, $data)
|
||
|
{
|
||
|
if (is_array($data)) {
|
||
|
$nonAttributes = array();
|
||
|
foreach ($data as $key => $val) {
|
||
|
//handle an attribute with elements
|
||
|
if ($key[0] == '@') {
|
||
|
$xml->writeAttribute(substr($key, 1), $val);
|
||
|
} else if ($key[0] == '%') {
|
||
|
if (is_array($val)) $nonAttributes = $val;
|
||
|
else $xml->text($val);
|
||
|
} elseif ($key[0] == '#') {
|
||
|
if (is_array($val)) $nonAttributes = $val;
|
||
|
else {
|
||
|
$xml->startElement(substr($key, 1));
|
||
|
$xml->writeCData($val);
|
||
|
$xml->endElement();
|
||
|
}
|
||
|
}else if($key[0] == "!"){
|
||
|
if (is_array($val)) $nonAttributes = $val;
|
||
|
else $xml->writeCData($val);
|
||
|
}
|
||
|
//ignore normal elements
|
||
|
else $nonAttributes[$key] = $val;
|
||
|
}
|
||
|
return $nonAttributes;
|
||
|
} else return $data;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Write XML as per Associative Array
|
||
|
*
|
||
|
* @param XMLWriter $xml object
|
||
|
* @param array $data Associative Data Array
|
||
|
*/
|
||
|
protected function writeEl(XMLWriter $xml, $data)
|
||
|
{
|
||
|
foreach ($data as $key => $value) {
|
||
|
if (is_array($value) && !$this->isAssoc($value)) { //numeric array
|
||
|
foreach ($value as $itemValue) {
|
||
|
if (is_array($itemValue)) {
|
||
|
$xml->startElement($key);
|
||
|
$itemValue = $this->writeAttr($xml, $itemValue);
|
||
|
$this->writeEl($xml, $itemValue);
|
||
|
$xml->endElement();
|
||
|
} else {
|
||
|
$itemValue = $this->writeAttr($xml, $itemValue);
|
||
|
$xml->writeElement($key, "$itemValue");
|
||
|
}
|
||
|
}
|
||
|
} else if (is_array($value)) { //associative array
|
||
|
$xml->startElement($key);
|
||
|
$value = $this->writeAttr($xml, $value);
|
||
|
$this->writeEl($xml, $value);
|
||
|
$xml->endElement();
|
||
|
} else { //scalar
|
||
|
$value = $this->writeAttr($xml, $value);
|
||
|
$xml->writeElement($key, "$value");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if array is associative with string based keys
|
||
|
* FROM: http://stackoverflow.com/questions/173400/php-arrays-a-good-way-to-check-if-an-array-is-associative-or-sequential/4254008#4254008
|
||
|
*
|
||
|
* @param array $array Array to check
|
||
|
* @return bool
|
||
|
*/
|
||
|
protected function isAssoc($array)
|
||
|
{
|
||
|
return (bool)count(array_filter(array_keys($array), 'is_string'));
|
||
|
}
|
||
|
}
|