135 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| /**
 | |
|  * Based on: http://stackoverflow.com/questions/99350/passing-php-associative-arrays-to-and-from-xml
 | |
|  */
 | |
| class ArrayToXML
 | |
| {
 | |
| 	private $version;
 | |
| 	private $encoding;
 | |
| 
 | |
| 	/**
 | |
| 	 * Construct ArrayToXML object with selected version and encoding
 | |
| 	 *
 | |
| 	 * for available values check XmlWriter docs http://www.php.net/manual/en/function.xmlwriter-start-document.php
 | |
| 	 * @param string $xmlVersion XML Version, default 1.0
 | |
| 	 * @param string $xmlEncoding XML Encoding, default UTF-8
 | |
| 	 */
 | |
| 	public function __construct($xmlVersion = '1.0', $xmlEncoding = 'UTF-8')
 | |
| 	{
 | |
| 		$this->version = $xmlVersion;
 | |
| 		$this->encoding = $xmlEncoding;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Build an XML Data Set
 | |
| 	 *
 | |
| 	 * @param array $data Associative Array containing values to be parsed into an XML Data Set(s)
 | |
| 	 * @param string $startElement Root Opening Tag, default data
 | |
| 	 * @return string XML String containing values
 | |
| 	 * @return mixed Boolean false on failure, string XML result on success
 | |
| 	 */
 | |
| 	public function buildXML($data, $startElement = 'data')
 | |
| 	{
 | |
| 		if (!is_array($data)) {
 | |
| 			$err = 'Invalid variable type supplied, expected array not found on line ' . __LINE__ . ' in Class: ' . __CLASS__ . ' Method: ' . __METHOD__;
 | |
| 			trigger_error($err);
 | |
| 			return false; //return false error occurred
 | |
| 		}
 | |
| 		$xml = new XmlWriter();
 | |
| 		$xml->openMemory();
 | |
| 		$xml->startDocument($this->version, $this->encoding);
 | |
| 		$xml->startElement($startElement);
 | |
| 
 | |
| 		$data = $this->writeAttr($xml, $data);
 | |
| 		$this->writeEl($xml, $data);
 | |
| 
 | |
| 		$xml->endElement(); //write end element
 | |
| 		//returns the XML results
 | |
| 		return $xml->outputMemory(true);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Write keys in $data prefixed with @ as XML attributes, if $data is an array.
 | |
| 	 * When an @ prefixed key is found, a '%' key is expected to indicate the element itself,
 | |
| 	 * and '#' prefixed key indicates CDATA content
 | |
| 	 *
 | |
| 	 * @param XMLWriter $xml object
 | |
| 	 * @param array $data with attributes filtered out
 | |
| 	 * @return array $data | $nonAttributes
 | |
| 	 */
 | |
| 	protected function writeAttr(XMLWriter $xml, $data)
 | |
| 	{
 | |
| 		if (is_array($data)) {
 | |
| 			$nonAttributes = array();
 | |
| 			foreach ($data as $key => $val) {
 | |
| 				//handle an attribute with elements
 | |
| 				if ($key[0] == '@') {
 | |
| 					$xml->writeAttribute(substr($key, 1), $val);
 | |
| 				} else if ($key[0] == '%') {
 | |
| 					if (is_array($val)) $nonAttributes = $val;
 | |
| 					else $xml->text($val);
 | |
| 				} elseif ($key[0] == '#') {
 | |
| 					if (is_array($val)) $nonAttributes = $val;
 | |
| 					else {
 | |
| 						$xml->startElement(substr($key, 1));
 | |
| 						$xml->writeCData($val);
 | |
| 						$xml->endElement();
 | |
| 					}
 | |
| 				}else if($key[0] == "!"){
 | |
| 					if (is_array($val)) $nonAttributes = $val;
 | |
| 					else $xml->writeCData($val);
 | |
| 				}
 | |
| 				//ignore normal elements
 | |
| 				else $nonAttributes[$key] = $val;
 | |
| 			}
 | |
| 			return $nonAttributes;
 | |
| 		} else return $data;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Write XML as per Associative Array
 | |
| 	 *
 | |
| 	 * @param XMLWriter $xml object
 | |
| 	 * @param array $data Associative Data Array
 | |
| 	 */
 | |
| 	protected function writeEl(XMLWriter $xml, $data)
 | |
| 	{
 | |
| 		foreach ($data as $key => $value) {
 | |
| 			if (is_array($value) && !$this->isAssoc($value)) { //numeric array
 | |
| 				foreach ($value as $itemValue) {
 | |
| 					if (is_array($itemValue)) {
 | |
| 						$xml->startElement($key);
 | |
| 						$itemValue = $this->writeAttr($xml, $itemValue);
 | |
| 						$this->writeEl($xml, $itemValue);
 | |
| 						$xml->endElement();
 | |
| 					} else {
 | |
| 						$itemValue = $this->writeAttr($xml, $itemValue);
 | |
| 						$xml->writeElement($key, "$itemValue");
 | |
| 					}
 | |
| 				}
 | |
| 			} else if (is_array($value)) { //associative array
 | |
| 				$xml->startElement($key);
 | |
| 				$value = $this->writeAttr($xml, $value);
 | |
| 				$this->writeEl($xml, $value);
 | |
| 				$xml->endElement();
 | |
| 			} else { //scalar
 | |
| 				$value = $this->writeAttr($xml, $value);
 | |
| 				$xml->writeElement($key, "$value");
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Check if array is associative with string based keys
 | |
| 	 * FROM: http://stackoverflow.com/questions/173400/php-arrays-a-good-way-to-check-if-an-array-is-associative-or-sequential/4254008#4254008
 | |
| 	 *
 | |
| 	 * @param array $array Array to check
 | |
| 	 * @return bool
 | |
| 	 */
 | |
| 	protected function isAssoc($array)
 | |
| 	{
 | |
| 		return (bool)count(array_filter(array_keys($array), 'is_string'));
 | |
| 	}
 | |
| }
 |