Parse a generic QTI element node into an array

@param SimpleXMLElement $xml
@return array
172368
public static function parseElementXml(SimpleXMLElement $xml){

        $attributes = array();
        foreach($xml->attributes() as $name => $value){
            $attributes[$name] = (string) $value;
        }

        $returnValue = array(
            'qtiClass' => $xml->getName()
        );

        if(count($attributes)){
            $returnValue['attributes'] = $attributes;
        }

        return $returnValue;
    }
823224
protected static function simpleXmlToArray($xml)
    {
        $ar = [];
        foreach ($xml->children() as $k => $v) {
            // recurse the child
            $child = self::simpleXmlToArray($v);

            // if it's not an array, then it was empty, thus a value/string
            if (count($child) == 0) {
                $child = self::getConvertedXmlValue($v);
            }

            // add the children attributes as if they where children
            foreach ($v->attributes() as $ak => $av) {
                if ($ak == 'id') {
                    // special exception: if there is a key named 'id'
                    // then we will name the current key after that id
                    $k = self::getConvertedXmlValue($av);
                } else {
                    // otherwise, just add the attribute like a child element
                    if (is_string($child)) {
                        $child = [];
                    }
                    $child[$ak] = self::getConvertedXmlValue($av);
                }
            }

            // if the $k is already in our children list, we need to transform
            // it into an array, else we add it as a value
            if (!in_array($k, array_keys($ar))) {
                $ar[$k] = $child;
            } else {
                // (This only applies to nested nodes that do not have an @id attribute)

                // if the $ar[$k] element is not already an array, then we need to make it one.
                // this is a bit of a hack, but here we check to also make sure that if it is an
                // array, that it has numeric keys.  this distinguishes it from simply having other
                // nested element data.
                if (!is_array($ar[$k]) || !isset($ar[$k][0])) {
                    $ar[$k] = [$ar[$k]];
                }

                $ar[$k][] = $child;
            }
        }

        return $ar;
    }
39413
protected function parseManifestToArray( \SimpleXMLElement $xml ) {

		foreach ( $xml->manifest->children() as $item ) {
			/** @var \SimpleXMLElement $item */
			// Get attributes
			$id = '';
			$type = '';
			$href = '';
			foreach ( $item->attributes() as $key => $val ) {
				if ( 'id' === $key ) {
					$id = (string) $val;
				} elseif ( 'media-type' === $key ) {
						$type = (string) $val;
				} elseif ( 'href' === $key ) {
						$href = $val;
				}
			}

						// Skip
			if ( 'application/xhtml+xml' !== $type ) {
				continue;
			}

			$this->manifest[ $id ] = [
				'type' => $type,
				'href' => $href,
			];
		}

	}
381480
public function xml2array($xml)
    {
        $xml = trim($xml);
        if (!$xml) {
            throw new EasyXMLException('You should provide a XML document.');
        }

        try {
            $xml = is_file($xml) ? file_get_contents($xml) : $xml;
            $dom = new DomDocument();
            $dom->loadXML($xml);
            return XML2Array::createArray($dom);
        } catch (\Exception $e) {
            throw new EasyXMLException('Invalid XML document given.');
        }
    }
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;
    }
997999
protected function childToArray(SimpleXmlElement $xml, $name)
    {
        if (!isset($xml->{$name})) {
            return array();
        }

        return $xml->{$name}->toPhpValue('array');
    }
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;
    }
606838
protected static function recursiveXMLToArray($xml)
    {
        $x = null;
        if ($xml instanceof SimpleXMLElement) {
            $attributes = $xml->attributes();
            foreach ($attributes as $k => $v) {
                if ($v) {
                    $a[$k] = (string) $v;
                }
            }
            $x = $xml;
            $xml = get_object_vars($xml);
        }
        if (is_array($xml)) {
            if (count($xml) === 0) {
                return (string)$x;
            } // for CDATA
            $r = [];
            foreach ($xml as $key => $value) {
                $r[$key] = self::recursiveXMLToArray($value);
            }
            // Attributes
            if (isset($a)) {
                $r['@'] = $a;
            }
            return $r;
        }

        return (string) $xml;
    }
655415
protected function xmlToArray($xml)
    {
        // Do not output libxml error messages to screen
        $useErrors = libxml_use_internal_errors(true);
        $array = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
        libxml_use_internal_errors($useErrors);

        // Fix the issue that XML parse empty data to new SimpleXMLElement object
        return array_map('strval', (array) $array);
    }
1172932
public static function parse($xml)
    {
        $data = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);

        if (is_object($data) && get_class($data) === 'SimpleXMLElement') {
            $data = self::arrarval($data);
        }

        return $data;
    }
1308200
protected static function loadXML($xml)
	{
		// Activate small nodes allocation and relax LibXML's hardcoded limits if applicable
		$flags = (LIBXML_VERSION >= 20700) ? LIBXML_COMPACT | LIBXML_PARSEHUGE : 0;

		$dom = new DOMDocument;
		$dom->loadXML($xml, $flags);

		return $dom;
	}
813929
protected function parseOptions(\SimpleXMLElement $nodes)
    {
        $options = [];

        foreach ($nodes as $node) {
            if (\count($node) > 0) {
                if (\count($node->value) > 0) {
                    $value = $this->parseValues($node->value);
                } elseif (\count($node->constraint) > 0) {
                    $value = $this->parseConstraints($node->constraint);
                } else {
                    $value = [];
                }
            } else {
                $value = XmlUtils::phpize($node);
                if (\is_string($value)) {
                    $value = trim($value);
                }
            }

            $options[(string) $node['name']] = $value;
        }

        return $options;
    }
62534
public static function parse($xml)
    {
        $backup = libxml_disable_entity_loader(true);

        $result = self::normalize(simplexml_load_string(self::sanitize($xml), 'SimpleXMLElement', LIBXML_COMPACT | LIBXML_NOCDATA | LIBXML_NOBLANKS));

        libxml_disable_entity_loader($backup);

        return $result;
    }
797386
protected static function parseAtom(\SimpleXMLElement $xml)
    {
        if (!isset($xml->entry)) {
            return false;
        }

        $url = '';

        foreach ($xml->link as $link) {
            $attributes = $link->attributes();

            if (empty($attributes->href) || ((string) $attributes->rel === 'self')) {
                continue;
            }
            $url = (string) $attributes->href;
            break;
        }

        return [
            'url' => $url,
            'items' => self::getAtomEntries($xml->entry),
        ];
    }
202125
public function parseXML($xml)
    {
        $document = new \DOMDocument();

        $previousValue = libxml_use_internal_errors(true);
        libxml_clear_errors();
        $result = $document->loadXML($xml);
        /** @var \libXMLError[] $errors */
        $errors = libxml_get_errors();
        libxml_clear_errors();
        libxml_use_internal_errors($previousValue);

        if (true !== $result) {
            $message = [];
            foreach ($errors as $error) {
                $message[] = sprintf(
                    '%d. [%s] %s in on line %d in position %d',
                    count($message) + 1,
                    $error->code,
                    str_replace(["\n", "\r"], '', $error->message),
                    $error->line,
                    $error->column
                );
            }
            throw new RuntimeException('Can not parse XML: ' . implode('; ', $message));
        }

        return $this->parseDocument($document);
    }
739565
protected function getArrayForSpecialCase($xml)
    {
        $regEx            = '#\s*(&lt;\?xml.*interface&gt;)\s*#is';
        $regExReplace     = '#\s*>\s*(&lt;\?xml.*interface&gt;)\s*<[^>]+>\s*#is';
        $regExReplaceWith = '/>';

        // what can happen is that the valid XML element suddenly has,
        // as its element content, a full version of url-encoded XML.
        if ( ! preg_match($regEx, $xml)) {
            return [0 => $xml];
        }
        $xml = preg_replace($regExReplace, $regExReplaceWith, $xml);

        return $this->parse($xml);
    }
1331937
private function buildArrayFromNode(SimpleXMLElement $node): array
    {
        $array = [];
        foreach ($node->children() as $child) {
            if ((string) $child !== '') {
                $array[] = (string) $child;
            }
        }

        return $array;
    }