note 79922 added to function.xml-parse-into-struct

From: Date: Wed, 19 Dec 2007 19:23:15 +0000
Subject: note 79922 added to function.xml-parse-into-struct
Groups: php.notes 
Request: Send a blank email to php-notes+get-133791@lists.php.net to get a copy of this message
This is extending what Alf Marius Foss Olsen had posted above. It takes into account array keys with the same name and uses an increment for them instead of overwriting the keys. I am using it for SOAP requests (20K - 150K) and it parses very fast compared to PEAR. <? class XMLParser { // raw xml private $rawXML; // xml parser private $parser = null; // array returned by the xml parser private $valueArray = array(); private $keyArray = array(); // arrays for dealing with duplicate keys private $duplicateKeys = array(); // return data private $output = array(); private $status; public function XMLParser($xml){ $this->rawXML = $xml; $this->parser = xml_parser_create(); return $this->parse(); } private function parse(){ $parser = $this->parser; xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); // Dont mess with my cAsE sEtTings xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); // Dont bother with empty info if(!xml_parse_into_struct($parser, $this->rawXML, $this->valueArray, $this->keyArray)){ $this->status = 'error: '.xml_error_string(xml_get_error_code($parser)).' at line '.xml_get_current_line_number($parser); return false; } xml_parser_free($parser); $this->findDuplicateKeys(); // tmp array used for stacking $stack = array(); $increment = 0; foreach($this->valueArray as $val) { if($val['type'] == "open") { //if array key is duplicate then send in increment if(array_key_exists($val['tag'], $this->duplicateKeys)){ array_push($stack, $this->duplicateKeys[$val['tag']]); $this->duplicateKeys[$val['tag']]++; } else{ // else send in tag array_push($stack, $val['tag']); } } elseif($val['type'] == "close") { array_pop($stack); // reset the increment if they tag does not exists in the stack if(array_key_exists($val['tag'], $stack)){ $this->duplicateKeys[$val['tag']] = 0; } } elseif($val['type'] == "complete") { //if array key is duplicate then send in increment if(array_key_exists($val['tag'], $this->duplicateKeys)){ array_push($stack, $this->duplicateKeys[$val['tag']]); $this->duplicateKeys[$val['tag']]++; } else{ // else send in tag array_push($stack, $val['tag']); } $this->setArrayValue($this->output, $stack, $val['value']); array_pop($stack); } $increment++; } $this->status = 'success: xml was parsed'; return true; } private function findDuplicateKeys(){ for($i=0;$i < count($this->valueArray); $i++) { // duplicate keys are when two complete tags are side by side if($this->valueArray[$i]['type'] == "complete"){ if( $i+1 < count($this->valueArray) ){ if($this->valueArray[$i+1]['tag'] == $this->valueArray[$i]['tag'] && $this->valueArray[$i+1]['type'] == "complete"){ $this->duplicateKeys[$this->valueArray[$i]['tag']] = 0; } } } // also when a close tag is before an open tag and the tags are the same if($this->valueArray[$i]['type'] == "close"){ if( $i+1 < count($this->valueArray) ){ if( $this->valueArray[$i+1]['type'] == "open" && $this->valueArray[$i+1]['tag'] == $this->valueArray[$i]['tag']) $this->duplicateKeys[$this->valueArray[$i]['tag']] = 0; } } } } private function setArrayValue(&$array, $stack, $value){ if ($stack) { $key = array_shift($stack); $this->setArrayValue($array[$key], $stack, $value); return $array; } else { $array = $value; } } public function getOutput(){ return $this->output; } public function getStatus(){ return $this->status; } } ?> Usage: $p = new XMLParser($xml); $p->getOutput(); ---- Server IP: 216.235.15.211 Probable Submitter: 206.174.196.146 ---- Manual Page -- http://www.php.net/manual/en/function.xml-parse-into-struct.php Edit -- https://master.php.net/note/edit/79922 Del: integrated -- https://master.php.net/note/delete/79922/integrated Del: useless -- https://master.php.net/note/delete/79922/useless Del: bad code -- https://master.php.net/note/delete/79922/bad+code Del: spam -- https://master.php.net/note/delete/79922/spam Del: non-english -- https://master.php.net/note/delete/79922/non-english Del: in docs -- https://master.php.net/note/delete/79922/in+docs Del: other reasons-- https://master.php.net/note/delete/79922 Reject -- https://master.php.net/note/reject/79922 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#133791) next »