Skip to content

Instantly share code, notes, and snippets.

@jbrooksuk
Created March 28, 2013 10:00
Show Gist options
  • Save jbrooksuk/5262093 to your computer and use it in GitHub Desktop.
Save jbrooksuk/5262093 to your computer and use it in GitHub Desktop.
<?php
ini_set('memory_limit', '-1');
set_time_limit(0);
class ArrayToXML {
public static $XML = NULL;
public static $ENCODING = 'UTF-8';
const XML_VERSION = '1.0';
const XML_ATTRIBUTES = '@attr';
const XML_VALUE = '@value';
const XML_CDATA = '@cdata';
public static function init($formatOutput = TRUE) {
self::$XML = new DOMDocument(self::XML_VERSION);
self::$XML->formatOutput = $formatOutput;
}
public static function &toXML($xNode, $aData = []) {
$XML = self::getRoot();
if(count($aData) > 0) {
$XML->appendChild(self::convert($xNode, $aData));
}else{
$xRoot = array_pop(array_keys($aData));
$XML->insertBefore(self::convert($xRoot), $aData[$rootElement]);
}
self::$XML = NULL; // Clear the node for the 2nd time use
return $XML;
}
public static function &convert($xNode, $aData = []) {
$XML = self::getRoot();
$node = $XML->createElement($xNode);
if(is_array($aData)) {
// Attributes
if(isset($aData[self::XML_ATTRIBUTES])) {
foreach($aData[self::XML_ATTRIBUTES] as $attrKey => $attrValue) {
if(!self::isValidTagName($attrKey))
throw new Exception("[ArrayToXML] Illegal character in attribute name. Attr: {$attrKey} in node: {$xNode}");
$setAttr = @$node->setAttribute($attrKey, self::boolString($attrValue));
}
unset($aData[self::XML_ATTRIBUTES]);
}
// Values
if(isset($aData[self::XML_VALUE])) {
$node->appendChild($XML->createTextNode(self::boolString($aData[self::XML_VALUE])));
unset($aData[self::XML_VALUE]);
return $node;
}else if(isset($aData[self::XML_CDATA])) {
$node->appendChild($XML->createCDATASection(self::boolString($aData[self::XML_CDATA])));
unset($aData[self::XML_CDATA]);
return $node;
}
if(is_array($aData)) {
foreach($aData as $dataKey => $dataValue) {
if(!self::isValidTagName($dataKey)) {
throw new Exception("[ArrayToXML] Illegal character in attribute name. Attr: {$dataKey} in node: {$xNode}");
}
if(is_array($dataValue) && is_numeric(key($dataValue))) {
foreach($dataValue as $subKey => $subVal) {
$node->appendChild(self::convert($dataKey, $subVal));
}
}else{
$node->appendChild(self::convert($dataKey, $dataValue));
}
unset($aData[$dataKey]);
}
}
}else{
if(is_null($aData)) {
$node->appendChild($XML->createTextNode(NULL));
}else{
$node->appendChild($XML->createTextNode(self::boolString($aData)));
}
}
return $node;
}
private static function boolString($bString) {
$bString = ($bString === TRUE ? 'true' : $bString);
$bString = ($bString === FALSE ? 'false' : $bString);
return $bString;
}
private static function getRoot() {
if(empty(self::$XML)) self::init();
return self::$XML;
}
private static function isValidTagName($tag){
$pattern = '/^[a-z_]+[a-z0-9\:\-\.\_]*[^:]*$/i';
return preg_match($pattern, $tag, $matches) && $matches[0] == $tag;
}
protected function __destruct(){
self::$XML = NULL;
}
}
function xmlstr_to_array($xmlstr) {
if($xmlstr === NULL) return FALSE;
$doc = new DOMDocument();
if($xmlstr !== '') {
$doc->loadXML($xmlstr);
return domnode_to_array($doc->documentElement);
}else{
return FALSE;
}
}
function domnode_to_array($node) {
$output = [];
switch ($node->nodeType) {
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
$output = trim($node->textContent);
break;
case XML_ELEMENT_NODE:
for ($i = 0, $m=$node->childNodes->length; $i < $m; $i++) {
$child = $node->childNodes->item($i);
$v = domnode_to_array($child);
if(isset($child->tagName)) {
$t = $child->tagName;
if(!isset($output[$t])) $output[$t] = [];
$output[$t][] = $v;
} elseif($v) {
$output = (string) $v;
}
}
if(is_array($output)) {
if($node->attributes->length) {
$a = [];
foreach($node->attributes as $attrName => $attrNode) {
$a[$attrName] = (string) $attrNode->value;
}
$output['@attributes'] = $a;
}
foreach ($output as $t => $v) {
if(is_array($v) && count($v) == 1 && $t !== '@attributes') $output[$t] = $v[0];
}
}
break;
}
return $output;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment