Converts a SimpleXML object to an Array recursively
ensuring all sub-elements are arrays as well.

@param string $sXml The SimpleXML object
@param array  $arr  The array into which to store results

@return array
438700
private function _sxml2arr($sXml, $arr = null)
    {
        foreach ((array) $sXml as $key => $value) {
            if (is_object($value) || (is_array($value))) {
                $arr[$key] = $this->_sxml2arr($value);
            } else {
                $arr[$key] = $value;
            }
        }

        return $arr;
    }
1287690
public function xmlToArray(\SimpleXMLElement $xml, $options = array())
    {
        $defaults = array(
            'namespaceSeparator' => ':', //you may want this to be something other than a colon
            'attributePrefix' => '@',   //to distinguish between attributes and nodes with the same name
            'alwaysArray' => array('entry'),   //array of xml tag names which should always become arrays
            'autoArray' => true,        //only create arrays for tags which appear more than once
            'textContent' => '$',       //key used for the text content of elements
            'autoText' => false,         //skip textContent key if node has no attributes or child nodes
            'keySearch' => false,       //optional search and replace on tag and attribute names
            'keyReplace' => false,       //replace values for above search values (as passed to str_replace())
        );
        $options = array_merge($defaults, $options);
        $namespaces = $xml->getDocNamespaces();
        $namespaces[''] = null; //add base (empty) namespace

        //get attributes from all namespaces
        $attributesArray = array();
        foreach ($namespaces as $prefix => $namespace) {
            foreach ($xml->attributes($namespace) as $attributeName => $attribute) {
                //replace characters in attribute name
                if ($options['keySearch']) {
                    $attributeName = str_replace($options['keySearch'], $options['keyReplace'], $attributeName);
                }
                $attributeKey = $options['attributePrefix']
                        .($prefix ? $prefix.$options['namespaceSeparator'] : '')
                        .$attributeName;
                $attributesArray[$attributeKey] = (string) $attribute;
            }
        }

        //get child nodes from all namespaces
        $tagsArray = array();
        foreach ($namespaces as $prefix => $namespace) {
            foreach ($xml->children($namespace) as $childXml) {
                //recurse into child nodes
                $childArray = $this->xmlToArray($childXml, $options);
                list($childTagName, $childProperties) = each($childArray);

                //replace characters in tag name
                if ($options['keySearch']) {
                    $childTagName = str_replace($options['keySearch'], $options['keyReplace'], $childTagName);
                }
                //add namespace prefix, if any
                if ($prefix) {
                    $childTagName = $prefix.$options['namespaceSeparator'].$childTagName;
                }

                if (!isset($tagsArray[$childTagName])) {
                    //only entry with this key
                    //test if tags of this type should always be arrays, no matter the element count
                    $tagsArray[$childTagName] =
                            in_array($childTagName, $options['alwaysArray']) || !$options['autoArray']
                            ? array($childProperties) : $childProperties;
                } elseif (
                    is_array($tagsArray[$childTagName]) && array_keys($tagsArray[$childTagName])
                    === range(0, count($tagsArray[$childTagName]) - 1)
                ) {
                    //key already exists and is integer indexed array
                    $tagsArray[$childTagName][] = $childProperties;
                } else {
                    //key exists so convert to integer indexed array with previous value in position 0
                    $tagsArray[$childTagName] = array($tagsArray[$childTagName], $childProperties);
                }
            }
        }

        //get text content of node
        $textContentArray = array();
        $plainText = trim((string) $xml);
        if ($plainText !== '') {
            $textContentArray[$options['textContent']] = $plainText;
        }

        //stick it all together
        $propertiesArray = !$options['autoText'] || $attributesArray || $tagsArray || ($plainText === '')
                ? array_merge($attributesArray, $tagsArray, $textContentArray) : $plainText;

        //return node as array
        return array(
            $xml->getName() => $propertiesArray,
        );
    }
610194
public static function fromXml($xml): array
    {
        if (!$xml) {
            throw new InvalidArgumentException('Convert To Array Error! Invalid Xml!');
        }

        libxml_disable_entity_loader(true);

        return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA), JSON_UNESCAPED_UNICODE), true);
    }
1047438
protected function processAuthorNode(array $xmlArray)
    {
        $author = [];
        $authorItem = $xmlArray[Resources::AUTHOR];

        if (is_array($authorItem)) {
            /** @var SimpleXMLElement $authorXmlInstance */
            foreach ($xmlArray[Resources::AUTHOR] as $authorXmlInstance) {
                $authorInstance = new Person();
                $authorInstance->parseXml($authorXmlInstance->asXML());
                $author[] = $authorInstance;
            }
        } else {
            $authorInstance = new Person();
            $authorInstance->parseXml($authorItem->asXML());
            $author[] = $authorInstance;
        }

        return $author;
    }
442314
private static function _unserializeRecursive(SimpleXMLElement $xml)
    {
        $result = [];
        $dataNamespace = Resources::DS_XML_NAMESPACE;
        /** @var SimpleXMLElement $child */
        foreach ($xml->children($dataNamespace) as $child) {
            if (count($child->children($dataNamespace)) > 0) {
                $value = [];
                $children = $child->children($dataNamespace);
                /** @var SimpleXMLElement $firstChild */
                $firstChild = $children[0];
                if ($firstChild->getName() == 'element') {
                    foreach ($children as $subChild) {
                        $value[] = self::_unserializeRecursive(
                            $subChild
                        );
                    }
                } else {
                    $value = self::_unserializeRecursive(
                        $child
                    );
                }
            } else {
                $value = (string) $child;
            }

            $result[$child->getName()] = $value;
        }

        return $result;
    }
1013325
private static function simpleXmlToArray($element)
    {
        //====================================================================//
        // Safety Check
        if (false === $element) {
            return false;
        }
        //====================================================================//
        // Init Result
        $result = array();
        //====================================================================//
        // Get First Level Childrens
        $children = $element->children();
        $isArrayElement = false;
        //====================================================================//
        // For All Childrens
        foreach ($children as $elementName => $node) {
            //====================================================================//
            // This Element is an ArrayElement
            $isArrayElement = true;
            //====================================================================//
            // If Element Doesn't Already Exists => Store as Single Element
            if (!isset($result[$elementName])) {
                $result[$elementName] = array();
                $result[$elementName] = self::simpleXmlToArray($node);

                continue;
            }
            //====================================================================//
            // Element Already Exists => Store as Array Element
            //====================================================================//
            // Convert Single Element to Array Element
            if (!is_array($result[$elementName])) {
                $singleElement = $result[$elementName];       // Store Firts Element
                $result[$elementName] = array();                    // Create New Array
                $result[$elementName][] = $singleElement;             // Append To Array
            }
            //====================================================================//
            // Append Array Element
            $result[$elementName][] = self::simpleXmlToArray($node);
        }
        //====================================================================//
        // Return Single Element
        if (!$isArrayElement && '' == $children->getName()) {
            $result = base64_decode((string) $element, true);
        }

        return $result;
    }
1164724
protected static function xmlToArray(\SimpleXMLElement $xml)/*# : array */
    {
        $arr = array();
        foreach ($xml as $element) {
            $tag = $element->getName();
            $ele = get_object_vars($element);
            if (!empty($ele)) {
                $arr[$tag] = $element instanceof \SimpleXMLElement ?
                    static::xmlToArray($element) :
                    $ele;
            } else {
                $arr[$tag] = trim($element);
            }
        }
        return $arr;
    }
1308462
public static function _getChildrenIndex ($arr)
	{
		
		$return	= array ();

		foreach ($arr as $child)
		{
			$return[] = $child->get ('id');
			$return = array_merge ($return, self::_getChildrenIndex ($child->children));
		}

		return $return;
		
	}
442783
private function array2xml($arr, $level = 1)
    {
        $str = ($level == 1) ? "<?xml version=\"1.0\" encoding=\"" . Config::get('default_charset') . "\"?>\r\n<root>\r\n" : '';
        $space = str_repeat("\t", $level);
        foreach ($arr as $key => $val) {
            if (is_numeric($key)) {
                $key = 'item';
            }
            if (!is_array($val)) {
                if (is_string($val) && preg_match('/[&<>"\'\?]+/', $val)) {
                    $str .= $space . "<$key><![CDATA[" . $val . ']]>' . "</$key>\r\n";
                } else {
                    $str .= $space . "<$key>" . $val . "</$key>\r\n";
                }
            } else {
                $str .= $space . "<$key>\r\n" . self::array2xml($val, $level + 1) . $space . "</$key>\r\n";
            }
        }
        if ($level == 1) {
            $str .= '</root>';
        }
        return $str;
    }
1097116
static public function xmlToArray($xml)
    {
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $values;
    }
1276236
private function xmlToElements($xml)
    {
        //====================================================================//
        // Convert XML to Object Recursively
        try {
            $result = simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOERROR);
        } catch (Exception $ex) {
            $this->fault = $ex->getMessage();

            return false;
        }

        return $result;
    }
57552
public function to_array($xml){
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $result;
    }
1110238
protected static function convertXmlToArray(\SimpleXMLElement $data)
    {
        $result = [];
        foreach ((array) $data as $index => $node) {
            $result[$index] = (\is_object($node)) ? static::convertXmlToArray($node) : trim((string) $node);
        }

        return $result;
    }
147548
public static function buildXml(SimpleXMLElement &$xml, $array) {
        if (is_array($array)) {
            foreach ($array as $key => $value) {

                // XML_NONE
                if (!is_array($value)) {
                    $xml->addChild($key, static::unbox($value));
                    continue;
                }

                // Multiple nodes of the same name
                if (Hash::isNumeric(array_keys($value))) {
                    foreach ($value as $kValue) {
                        if (is_array($kValue)) {
                            static::buildXml($xml, array($key => $kValue));
                        } else {
                            $xml->addChild($key, static::unbox($kValue));
                        }
                    }

                // XML_GROUP
                } else if (isset($value['attributes'])) {
                    if (!isset($value['value'])) {
                        $value['value'] = null;
                    }

                    if (is_array($value['value'])) {
                        $node = $xml->addChild($key);
                        static::buildXml($node, $value['value']);
                    } else {
                        $node = $xml->addChild($key, static::unbox($value['value']));
                    }

                    if (!empty($value['attributes'])) {
                        foreach ($value['attributes'] as $aKey => $aValue) {
                            $node->addAttribute($aKey, static::unbox($aValue));
                        }
                    }

                // XML_MERGE
                } else if (isset($value['value'])) {
                    $node = $xml->addChild($key, $value['value']);
                    unset($value['value']);

                    if (!empty($value)) {
                        foreach ($value as $aKey => $aValue) {
                            if (is_array($aValue)) {
                                static::buildXml($node, array($aKey => $aValue));
                            } else {
                                $node->addAttribute($aKey, static::unbox($aValue));
                            }
                        }
                    }

                // XML_ATTRIBS
                } else {
                    $node = $xml->addChild($key);

                    if (!empty($value)) {
                        foreach ($value as $aKey => $aValue) {
                            if (is_array($aValue)) {
                                static::buildXml($node, array($aKey => $aValue));
                            } else {
                                $node->addChild($aKey, static::unbox($aValue));
                            }
                        }
                    }
                }
            }
        }

        return $xml;
    }
1020687
public function generateXML (&$doc, $arr = FALSE, $xml = FALSE)
	{
		
		// If there is DOMElement reate the root element
		
		if ($xml === FALSE)
		{	
			$xml	= $doc->createElement (strtolower ($this->rootNode));	
		}
		
		// If there is no element set to the result
		
		if ($arr === FALSE)
		{
			$arr	= $this->result;
		}
			
		// For each element in the element types
		
		foreach ($arr as $key => $val)
		{
			
			// If the element is an object and the key is a number
			
			if (is_object ($val) && is_numeric ($key))
			{
				
				// Set key to class name
				
				$key	= get_class ($val);
				
			}
			
			// Else if there is an array key 'class'
			
			else if (is_array ($val) && array_key_exists ('class', $val))
			{
				
				// Set key to class name
				
				$key	= $val['class'];
				
				// Remove class key
				
				unset ($val['class']);
				
			}
			
			// Else if the key is a number
			
			else if (is_numeric ($key))
			{
				
				// Set key to string
				
				$key	= 'result_' . $key;
				
			}
			
			// Create a new element
			
			$element	= $doc->createElement (strtolower ($key));
			
			// If the value is an array generate XML
			
			if (is_array ($val))
			{
				$element	= $this->generateXML ($doc, $val, $element);
			}
			
			// Else set the element value
			
			else
			{
				$element->nodeValue	= htmlentities ($val);
			}
			
			// Append element
			
			$xml->appendChild ($element);
			
		}
		
		return $xml;
		
	}
750402
private function xmlToArray(\SimpleXMLIterator $sxi)
    {
        $a = array();

        for ($sxi->rewind(); $sxi->valid(); $sxi->next()) {
            $t = array();
            $current = $sxi->current();
            $attributes = $current->attributes();
            $name = isset($attributes->_key) ? strval($attributes->_key) : $sxi->key();

            // save attributes
            foreach ($attributes as $att_key => $att_value) {
                if ($att_key !== '_key') {
                    $t[$att_key] = strval($att_value);
                }
            }

            // we parse nodes
            if ($sxi->hasChildren()) { // children
                $t = array_merge($t, $this->xmlToArray($current));
            } else { // it's a leaf
                if (empty($t)) {
                    $t = strval($current); // strval will call _toString()
                } else {
                    $t['_value'] = strval($current); // strval will call _toString()
                }
            }

            $a[$name] = $t;
        }

        return $a;
    }
769472
protected function convertXmlToArray($xml)
    {
        if (is_string($xml)) {
            $xml = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
        }
        $result = (array) $xml;
        foreach ($result as $key => $value) {
            if (!is_scalar($value)) {
                $result[$key] = $this->convertXmlToArray($value);
            }
        }
        return $result;
    }