Skip to content

Instantly share code, notes, and snippets.

@scarstens
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scarstens/11392176 to your computer and use it in GitHub Desktop.
Save scarstens/11392176 to your computer and use it in GitHub Desktop.
Array to XML Using XDOMDocument
<?php
class XDOMElement extends DOMElement {
function __construct($name, $value = null, $namespaceURI = null) {
parent::__construct($name, null, $namespaceURI);
}
}
class XDOMDocument extends DOMDocument {
function __construct($version = null, $encoding = null) {
parent::__construct($version, $encoding);
$this->registerNodeClass('DOMElement', 'XDOMElement');
}
function createElement($name, $value = null, $namespaceURI = null) {
$element = new XDOMElement($name, $value, $namespaceURI);
$element = $this->importNode($element);
if (!empty($value)) {
$element->appendChild(new DOMText($value));
}
return $element;
}
}
class array2xml extends XDOMDocument {
public $nodeName;
private $xpath;
private $root;
private $node_name;
/**
* Constructor
* Set up the DOM environment
* @param string $root The name of the root node
* @param string $node_name
* @internal param string $nod_name The name numeric keys are called
*/
public function __construct($root = 'root', $node_name = 'node') {
parent::__construct();
/*** set the encoding ***/
$this->encoding = "ISO-8859-1";
$this->xmlVersion = "1.0";
/*** format the output ***/
$this->formatOutput = TRUE;
/*** set the node names ***/
$this->node_name = $node_name;
/*** create the root element ***/
$this->root = $this->appendChild($this->createElement($root));
$this->xpath = new DomXPath($this);
}
/*
* creates the XML representation of the array
*
* @access public
* @param array $arr The array to convert
* @aparam string $node The name given to child nodes when recursing
*
*/
public function createNode($arr, $node = NULL) {
echo 'create node:'.PHP_EOL;
if (is_null($node)) {
echo 'root node';
$node = $this->root;
}
print_r($arr);echo PHP_EOL;
if(count($arr) > 1 || is_array($arr) || is_object($arr)) foreach ($arr as $element => $value) {
$element = is_numeric($element) ? $this->node_name : $element;
$elementXMLSafe = htmlentities($element, ENT_XML1);
$elementXMLSafe = str_replace ("'", "", $elementXMLSafe);
$elementXMLSafe = str_replace (" ", "_", $elementXMLSafe);
$elementXMLSafe = preg_replace ('/[^\p{L}\p{N}]/u', '_', $elementXMLSafe);
//@TODO: Add Original element name into attribute so data is not lost
$child = $this->createElement((string)$elementXMLSafe, (is_array($value) || is_object($value)) ? NULL : (string)$value);
$node->appendChild($child);
if (is_array($value) || is_object($value)) {
self::createNode((array)$value, $child);
}
}
}
/*
* Return the generated XML as a string
*
* @access public
* @return string
*
*/
public function __toString() {
return $this->saveXML();
}
/*
* array2xml::query() - perform an XPath query on the XML representation of the array
* @param str $query - query to perform
* @return mixed
*/
public function query($query) {
return $this->xpath->evaluate($query);
}
} // end of class
$sampleObject = new stdClass();
$sampleObject->property = array('Should be converted to array ','by Array 2 XML Function');
$arrayFourLevelsDeepWithObjects = array(
1=>'handle numerical arrays',
'Level_ONE_A' => 'Easy to parse',
'Level_FOUR_BY_ONE' => array(
'Level_FOUR_BY_TWO' => array(
'Object_Test_Is_Next'=>null,
'oLevel_FOUR_BY_THREE_A_OBJECT_NESTED_IN_ARRAY'=>$sampleObject,
'Level_FOUR_BY_THREE_B' => array(
'Level_FOUR_BY_FOUR' => array(
'attribute_ONE'=>'blue',
'attribute_TWO'=>null,
'attribute_THREE'=>3,
'attribute_FOUR'=>'',
'attribute_FIVE'=>true,
'attribute_SIX'=>false
)
),
)
),
'Level_ONE_B' => 'Easy to parse too',
'HANDLE_NUMBERS_IN_ARRAYS_1'=>'Dont just crash, show this node',
'Handle Spaces'=>'Dont just crash, show this node',
'Handle (parens)'=>'Dont just crash, show this node',
);
//execute test of Array to XML Class
build_xml($arrayFourLevelsDeepWithObjects, 'object');
function build_xml($a, $node='item'){
//require_once(__DIR__.'/lib/functions.classes-array2xml.inc.php');
header('Content-Type: text/xml');
$xml = new array2xml('data', $node);
$xml->createNode( $a );
echo $xml;
exit;
}
@scarstens
Copy link
Author

updated, now with test case built into file, works great. just need help figuring out how to set an attribute/proptery on the XML object. Not sure how to do it, but would be best to store original array key labels since we have to butcher them to stop DOMElement from breaking on the "invalid character" exception. help!?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment