Microweber\Utils\lib\XmlStreamer::parse PHP Method

parse() public method

Starts the streaming and parsing of the XML file.
public parse ( )
    public function parse()
    {
        $counter = 0;
        $continue = true;
        while ($continue) {
            $continue = $this->readNextChunk();
            ++$counter;
            if (!isset($this->rootNode)) {
                // Find root node
                if (isset($this->customRootNode)) {
                    $customRootNodePos = strpos($this->chunk, "<{$this->customRootNode}");
                    if ($customRootNodePos !== false) {
                        // Found custom root node
                        // Support attributes
                        $closer = strpos(substr($this->chunk, $customRootNodePos), '>');
                        $readFromChunkPos = $customRootNodePos + $closer + 1;
                        // Custom child node?
                        if (isset($this->customChildNode)) {
                            // Find it in the chunk
                            $customChildNodePos = strpos(substr($this->chunk, $readFromChunkPos), "<{$this->customChildNode}");
                            if ($customChildNodePos !== false) {
                                // Found it!
                                $readFromChunkPos = $readFromChunkPos + $customChildNodePos;
                            } else {
                                // Didn't find it - read a larger chunk and do everything again
                                continue;
                            }
                        }
                        $this->rootNode = $this->customRootNode;
                        $this->readFromChunkPos = $readFromChunkPos;
                    } else {
                        // Clear chunk to save memory, it doesn't contain the root anyway
                        $this->readFromChunkPos = 0;
                        $this->chunk = '';
                        continue;
                    }
                } else {
                    // XML1.0 standard allows almost all Unicode characters even Chinese and Cyrillic.
                    // see: http://en.wikipedia.org/wiki/XML#International_use
                    preg_match('/<([^>\\?]+)>/', $this->chunk, $matches);
                    if (isset($matches[1])) {
                        // Found root node
                        $this->rootNode = $matches[1];
                        $this->readFromChunkPos = strpos($this->chunk, $matches[0]) + strlen($matches[0]);
                    } else {
                        // Clear chunk to save memory, it doesn't contain the root anyway
                        $this->readFromChunkPos = 0;
                        $this->chunk = '';
                        continue;
                    }
                }
            }
            while (true) {
                $fromChunkPos = substr($this->chunk, $this->readFromChunkPos);
                // Find element
                // XML1.0 standard allows almost all Unicode characters even Chinese and Cyrillic.
                // see: http://en.wikipedia.org/wiki/XML#International_use
                preg_match('/<([^>]+)>/', $fromChunkPos, $matches);
                if (isset($matches[1])) {
                    // Found element
                    $element = $matches[1];
                    // Is there an end to this element tag?
                    $spacePos = strpos($element, ' ');
                    $crPos = strpos($element, "\r");
                    $lfPos = strpos($element, "\n");
                    $tabPos = strpos($element, "\t");
                    // find min. (exclude false, as it would convert to int 0)
                    $aPositionsIn = array($spacePos, $crPos, $lfPos, $tabPos);
                    $aPositions = array();
                    foreach ($aPositionsIn as $iPos) {
                        if ($iPos !== false) {
                            $aPositions[] = $iPos;
                        }
                    }
                    $minPos = $aPositions === array() ? false : min($aPositions);
                    if ($minPos !== false && $minPos != 0) {
                        $sElementName = substr($element, 0, $minPos);
                        $endTag = '</' . $sElementName . '>';
                    } else {
                        $sElementName = $element;
                        $endTag = "</{$sElementName}>";
                    }
                    $endTagPos = false;
                    // try selfclosing first!
                    // NOTE: selfclosing is inside the element
                    $lastCharPos = strlen($element) - 1;
                    if (substr($element, $lastCharPos) == '/') {
                        $endTag = '/>';
                        $endTagPos = $lastCharPos;
                        $iPos = strpos($fromChunkPos, '<');
                        if ($iPos !== false) {
                            // correct difference between $element and $fromChunkPos
                            // "+1" is for the missing '<' in $element
                            $endTagPos += $iPos + 1;
                        }
                    }
                    if ($endTagPos === false) {
                        $endTagPos = strpos($fromChunkPos, $endTag);
                    }
                    if ($endTagPos !== false) {
                        // Found end tag
                        $endTagEndPos = $endTagPos + strlen($endTag);
                        $elementWithChildren = trim(substr($fromChunkPos, 0, $endTagEndPos));
                        $continueParsing = $this->processNode($elementWithChildren, $sElementName, $this->nodeIndex++);
                        $this->chunk = substr($this->chunk, strpos($this->chunk, $endTag) + strlen($endTag));
                        $this->readFromChunkPos = 0;
                        if (isset($continueParsing) && $continueParsing === false) {
                            $this->chunkCompleted();
                            break 2;
                        }
                    } else {
                        break;
                    }
                } else {
                    break;
                }
            }
            $this->chunkCompleted();
        }
        return isset($this->rootNode);
        fclose($this->handle);
    }