src/ArrayToXML.php
<?php
/**
* Softaculous Related Functionality
* @author Joe Huss <detain@interserver.net>
* @copyright 2019
* @package MyAdmin-Softaculous-Licensing
* @category Licenses
*/
namespace Detain\MyAdminSoftaculous;
/**
* Converts an Array to XML
*/
class ArrayToXML
{
/**
* The main function for converting to an XML document.
* Pass in a multi dimensional array and this recursively loops through and builds up an XML document.
*
* @param array $data
* @param string $rootNodeName - what you want the root node to be - defaults to data.
* @param \SimpleXMLElement $xml - should only be used recursively
* @return string XML
*/
public function toXML($data, $rootNodeName = 'ResultSet', $xml = null)
{
if (null === $xml) { //$xml = simplexml_load_string( "" );
$xml = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$rootNodeName />");
}
// loop through the data passed in.
foreach ($data as $key => $value) {
$numeric = false;
// no numeric keys in our xml please!
if (is_numeric($key)) {
$numeric = 1;
$key = $rootNodeName;
}
// delete any char not allowed in XML element names
$key = preg_replace('/[^a-z0-9\-\_\.\:]/i', '', $key);
// if there is another array found recursively call this function
if (is_array($value)) {
$node = self::isAssoc($value) || $numeric ? $xml->addChild($key) : $xml;
// recursive call.
if ($numeric) {
$key = 'anon';
}
self::toXML($value, $key, $node);
} else {
// add single node.
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
$xml->addChild($key, $value);
}
}
// pass back as XML
return $xml->asXML();
// if you want the XML to be formatted, use the below instead to return the XML
//$doc = new DOMDocument('1.0');
//$doc->preserveWhiteSpace = FALSE;
//$doc->loadXML( $xml->asXML() );
//$doc->formatOutput = TRUE;
//return $doc->saveXML();
}
/**
* Convert an XML document to a multi dimensional array
* Pass in an XML document (or SimpleXMLElement object) and this recursively loops through and builds a representative array
*
* @param string|\SimpleXMLElement $xml - XML document - can optionally be a SimpleXMLElement object
* @return array|string
*/
public function toArray($xml)
{
if (is_string($xml)) {
$xml = new \SimpleXMLElement($xml);
}
$children = $xml->children();
if (!$children) {
return (string) $xml;
}
$arr = [];
foreach ($children as $key => $node) {
$node = self::toArray($node);
// support for 'anon' non-associative arrays
if ($key == 'anon') {
$key = count($arr);
}
// if the node is already set, put it into an array
if (isset($arr[$key])) {
if (!is_array($arr[$key]) || $arr[$key][0] == null) {
$arr[$key] = [$arr[$key]];
}
$arr[$key][] = $node;
} else {
$arr[$key] = $node;
}
}
return $arr;
}
// determine if a variable is an associative array
/**
* @param $array
* @return bool
*/
public function isAssoc($array)
{
return (is_array($array) && 0 !== count(array_diff_key($array, array_keys(array_keys($array)))));
}
}