protected function parseElement($name, $callbacks, LocatorInterface $locator)
    {
        $hasChildren = !$this->isEmptyElement;
        $attributes  = $this->hasAttributes ? $this->getAttributes() : [];
        $children    = [];

        $callback = 'onBefore' . ucfirst($name);

        if (isset($callbacks[$callback])) {
            $attributes = call_user_func($callbacks[$callback], $attributes);
        }

        if ($hasChildren) {
            while ($this->read()) {
                $currentName = $this->name;

                if ($this->nodeType == \XMLReader::END_ELEMENT && $currentName == $name) {
                    break;
                }

                if ($this->nodeType == \XMLReader::ELEMENT) {
                    $child = $this->parseElement($currentName, $callbacks, $locator);

                    if (isset($child->name)) {
                        $children[$currentName][$child->name] = $child;
                    } else {
                        $children[$currentName][] = $child;
                    }
                } elseif ($currentName[0] == '#') {
                    $text = trim($this->value);

                    if (!empty($text)) {
                        $children[$currentName] = $text;
                    }
                } else {
                    throw new InvalidElementException("Unknown element {$currentName} => {$this->value}");
                }
            }
        }

        $className = __NAMESPACE__ . '\\' . ucfirst($name);

        if (!class_exists($className)) {
            $className = __NAMESPACE__ . '\\Element';
        }

        $element = new $className(array_merge($attributes, $children));

        $callback = 'onAfter' . ucfirst($name);

        if (isset($callbacks[$callback])) {
            call_user_func($callbacks[$callback], $element, $locator);
        }

        return $element;
    }
protected function parseElement($name, $callbacks, LocatorInterface $locator)
    {
        $hasChildren = !$this->isEmptyElement;
        $attributes  = $this->hasAttributes ? $this->getAttributes() : [];
        $children    = [];

        $callback = 'onBefore' . ucfirst($name);

        if (isset($callbacks[$callback])) {
            $attributes = call_user_func($callbacks[$callback], $attributes);
        }

        if ($hasChildren) {
            while ($this->read()) {
                $currentName = $this->name;

                if ($this->nodeType == \XMLReader::END_ELEMENT && $currentName == $name) {
                    break;
                }

                if ($this->nodeType == \XMLReader::ELEMENT) {
                    $child = $this->parseElement($currentName, $callbacks, $locator);

                    if (isset($child->name)) {
                        $children[$currentName][$child->name] = $child;
                    } else {
                        $children[$currentName][] = $child;
                    }
                } elseif ($currentName[0] == '#') {
                    $text = trim($this->value);

                    if (!empty($text)) {
                        $children[$currentName] = $text;
                    }
                } else {
                    throw new InvalidElementException("Unknown element {$currentName} => {$this->value}");
                }
            }
        }

        $className = __NAMESPACE__ . '\\' . ucfirst($name);

        if (!class_exists($className)) {
            $className = __NAMESPACE__ . '\\Element';
        }

        $element = new $className(array_merge($attributes, $children));

        $callback = 'onAfter' . ucfirst($name);

        if (isset($callbacks[$callback])) {
            call_user_func($callbacks[$callback], $element, $locator);
        }

        return $element;
    }
protected function parseElement ( $ name , $ callbacks , LocatorInterface $ locator ) { $ hasChildren = ! $ this -> isEmptyElement ; $ attributes = $ this -> hasAttributes ? $ this -> getAttributes ( ) : [ ] ; $ children = [ ] ; $ callback = 'onBefore' . ucfirst ( $ name ) ; if ( isset ( $ callbacks [ $ callback ] ) ) { $ attributes = call_user_func ( $ callbacks [ $ callback ] , $ attributes ) ; } if ( $ hasChildren ) { while ( $ this -> read ( ) ) { $ currentName = $ this -> name ; if ( $ this -> nodeType == \ XMLReader :: END_ELEMENT && $ currentName == $ name ) { break ; } if ( $ this -> nodeType == \ XMLReader :: ELEMENT ) { $ child = $ this -> parseElement ( $ currentName , $ callbacks , $ locator ) ; if ( isset ( $ child -> name ) ) { $ children [ $ currentName ] [ $ child -> name ] = $ child ; } else { $ children [ $ currentName ] [ ] = $ child ; } } elseif ( $ currentName [ 0 ] == '#' ) { $ text = trim ( $ this -> value ) ; if ( ! empty ( $ text ) ) { $ children [ $ currentName ] = $ text ; } } else { throw new InvalidElementException ( "Unknown element {$currentName} => {$this->value}" ) ; } } } $ className = __NAMESPACE__ . '\\' . ucfirst ( $ name ) ; if ( ! class_exists ( $ className ) ) { $ className = __NAMESPACE__ . '\\Element' ; } $ element = new $ className ( array_merge ( $ attributes , $ children ) ) ; $ callback = 'onAfter' . ucfirst ( $ name ) ; if ( isset ( $ callbacks [ $ callback ] ) ) { call_user_func ( $ callbacks [ $ callback ] , $ element , $ locator ) ; } return $ element ; }
Recursively parse the element tree.

@param   string           $name      Name of the current element
@param   Callable[]       $callbacks Hooks for pre- and postprocessing of elements
@param   LocatorInterface $locator   The XML description file locator

@return  Element  The parsed structure
Recursively parse the element tree .