From d0972f63ac066bb45613e8f8a880ab4dcee72aea Mon Sep 17 00:00:00 2001 From: sjcastroe Date: Tue, 9 Dec 2014 14:28:16 -0800 Subject: [PATCH] Added XML compatibility to YamlGameLoader class. XML2Array used to parse XML string to multidimensional array. --- src/Loader/XML2Array.php | 163 ++++++++++++++++++++++++++++++++++ src/Loader/YamlGameLoader.php | 30 ++++++- 2 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 src/Loader/XML2Array.php diff --git a/src/Loader/XML2Array.php b/src/Loader/XML2Array.php new file mode 100644 index 0000000..18d4679 --- /dev/null +++ b/src/Loader/XML2Array.php @@ -0,0 +1,163 @@ +. + */ +namespace LSS; +use \DOMDocument; +use \Exception; + +/** + * XML2Array: A class to convert XML to array in PHP + * It returns the array which can be converted back to XML using the Array2XML script + * It takes an XML string or a DOMDocument object as an input. + * + * See Array2XML: http://www.lalit.org/lab/convert-php-array-to-xml-with-attributes + * + * Author : Lalit Patel + * Website: http://www.lalit.org/lab/convert-xml-to-array-in-php-xml2array + * License: Apache License 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * Version: 0.1 (07 Dec 2011) + * Version: 0.2 (04 Mar 2012) + * Fixed typo 'DomDocument' to 'DOMDocument' + * + * Usage: + * $array = XML2Array::createArray($xml); + */ + +class XML2Array { + + private static $xml = null; + private static $encoding = 'UTF-8'; + + /** + * Initialize the root XML node [optional] + * @param $version + * @param $encoding + * @param $format_output + */ + public static function init($version = '1.0', $encoding = 'UTF-8', $format_output = true) { + self::$xml = new DOMDocument($version, $encoding); + self::$xml->formatOutput = $format_output; + self::$encoding = $encoding; + } + + /** + * Convert an XML to Array + * @param string $node_name - name of the root node to be converted + * @param array $arr - aray to be converterd + * @return DOMDocument + */ + public static function &createArray($input_xml) { + $xml = self::getXMLRoot(); + if(is_string($input_xml)) { + $parsed = $xml->loadXML($input_xml); + if(!$parsed) { + throw new Exception('[XML2Array] Error parsing the XML string.'); + } + } else { + if(get_class($input_xml) != 'DOMDocument') { + throw new Exception('[XML2Array] The input XML object should be of type: DOMDocument.'); + } + $xml = self::$xml = $input_xml; + } + $array[$xml->documentElement->tagName] = self::convert($xml->documentElement); + self::$xml = null; // clear the xml node in the class for 2nd time use. + return $array; + } + + /** + * Convert an Array to XML + * @param mixed $node - XML as a string or as an object of DOMDocument + * @return mixed + */ + private static function &convert($node) { + $output = array(); + + switch ($node->nodeType) { + case XML_CDATA_SECTION_NODE: + $output['@cdata'] = trim($node->textContent); + break; + + case XML_TEXT_NODE: + $output = trim($node->textContent); + break; + + case XML_ELEMENT_NODE: + + // for each child node, call the covert function recursively + for ($i=0, $m=$node->childNodes->length; $i<$m; $i++) { + $child = $node->childNodes->item($i); + $v = self::convert($child); + if(isset($child->tagName)) { + $t = $child->tagName; + + // assume more nodes of same kind are coming + if(!isset($output[$t])) { + $output[$t] = array(); + } + $output[$t][] = $v; + } else { + //check if it is not an empty text node + if($v !== '') { + $output = $v; + } + } + } + + if(is_array($output)) { + // if only one node of its kind, assign it directly instead if array($value); + foreach ($output as $t => $v) { + if(is_array($v) && count($v)==1) { + $output[$t] = $v[0]; + } + } + if(empty($output)) { + //for empty nodes + $output = ''; + } + } + + // loop through the attributes and collect them + if($node->attributes->length) { + $a = array(); + foreach($node->attributes as $attrName => $attrNode) { + $a[$attrName] = (string) $attrNode->value; + } + // if its an leaf node, store the value in @value instead of directly storing it. + if(!is_array($output)) { + $output = array('@value' => $output); + } + $output['@attributes'] = $a; + } + break; + } + return $output; + } + + /* + * Get the root XML node, if there isn't one, create it. + */ + private static function getXMLRoot(){ + if(empty(self::$xml)) { + self::init(); + } + return self::$xml; + } +} diff --git a/src/Loader/YamlGameLoader.php b/src/Loader/YamlGameLoader.php index 7a22168..cf57c29 100644 --- a/src/Loader/YamlGameLoader.php +++ b/src/Loader/YamlGameLoader.php @@ -8,8 +8,11 @@ namespace SDPHP\PHPMicrork\Loader; +include 'XML2Array.php'; + use Symfony\Component\Config\Loader\FileLoader; use Symfony\Component\Yaml\Yaml; +use LSS\XML2Array; /** * YamlLevelLoader - Description. @@ -18,6 +21,26 @@ */ class YamlGameLoader extends FileLoader { + /** + * @param mixed $resource + * @return array + */ + private function parse($resource) + { + $file_type = pathinfo($resource, PATHINFO_EXTENSION); + switch ($file_type) { + case 'yml': + return Yaml::parse($resource); + break; + case 'xml': + $xml_string = implode("", file($resource)); + $xml_array = XML2Array::createArray($xml_string); + $root_tag = key($xml_array); + return $xml_array[$root_tag]; + break; + } + } + /** * @param mixed $resource * @param null $type @@ -25,14 +48,14 @@ class YamlGameLoader extends FileLoader */ public function load($resource, $type = null) { - $config = Yaml::parse($this->locator->locate($resource, null, true)); + $config = $this->parse($this->locator->locate($resource, null, true)); if (isset($config['world']['level_info'])) { // if is world configuration load levels $levels = []; foreach($config['world']['level_info'] as $levelName => $levelPath) { - $levels['levels'][$levelName] = Yaml::parse($this->locator->locate($levelPath, null, true)); + $levels['levels'][$levelName] = $this->parse($this->locator->locate($levelPath, null, true)); } $config = array_merge($config, $levels); @@ -43,6 +66,7 @@ public function load($resource, $type = null) public function supports($resource, $type = null) { - return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION); + $file_type = pathinfo($resource, PATHINFO_EXTENSION); + return is_string($resource) && ('yml' === $file_type || 'xml' === $file_type ); } }