scarstens
4/29/2014 - 6:35 AM

Array to XML Using XDOMDocument

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;
}