Created
March 28, 2013 10:00
-
-
Save jbrooksuk/5262093 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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