dpace32 Posted October 19, 2010 Share Posted October 19, 2010 Hello - First time poster and pretty new to PHP. I have tried to research this before posting but I couldn't find any tutorials with this exact scenario. I am trying to create a PHP file that reads an XML file with the following layout: <Root> - <Vehicle="Red"> <Trip>1108</Trip> <Platform>123RFIES</Platform> <InformationType>Slow</InformationType> </Red> - <Vehicle="Red"> <Trip>1108</Trip> <Platform>123RSHAS</Platform> <InformationType>Fast</InformationType> </Red> I am using the following PHP: <?php $file = "Vehicle.xml"; function contents($parser, $data){ echo $data; } function startTag($parser, $data){ echo "<b>"; } function endTag($parser, $data){ echo "</b><br />"; } $xml_parser = xml_parser_create(); xml_set_element_handler($xml_parser, "startTag", "endTag"); xml_set_character_data_handler($xml_parser, "contents"); $fp = fopen($file, "r"); $data = fread($fp, 80000); if(!(xml_parse($xml_parser, $data, feof($fp)))){ die("Error on line " . xml_get_current_line_number($xml_parser)); } xml_parser_free($xml_parser); fclose($fp); ?> Using this code I can read the entire XML and display it on the webpage. What I am trying to do is filter it so it only displays when InformationType = Fast and only display the Trip and the InformationType. Where do I add this filter logic? Thank you in advance! -Adam Quote Link to comment https://forums.phpfreaks.com/topic/216312-help-with-php-that-reads-a-simple-xml-file/ Share on other sites More sharing options...
PFMaBiSmAd Posted October 20, 2010 Share Posted October 20, 2010 Because the three call-back functions - startTag, endTag, and contents are completely independent and the xml_parser_ does not provide any way to communicate the current state between the functions, it is better if you wrap your code with an OOP/Class so that you can use class variables to communicate the current state between the functions. Once you do this, you can set a flag(s) when you detect the correct startTag value(s) so that you only process the data that matches the tag(s) you are looking for. Quote Link to comment https://forums.phpfreaks.com/topic/216312-help-with-php-that-reads-a-simple-xml-file/#findComment-1124162 Share on other sites More sharing options...
dpace32 Posted October 20, 2010 Author Share Posted October 20, 2010 Because the three call-back functions - startTag, endTag, and contents are completely independent and the xml_parser_ does not provide any way to communicate the current state between the functions, it is better if you wrap your code with an OOP/Class so that you can use class variables to communicate the current state between the functions. Once you do this, you can set a flag(s) when you detect the correct startTag value(s) so that you only process the data that matches the tag(s) you are looking for. hmmm can you give me an example? Thanks! Quote Link to comment https://forums.phpfreaks.com/topic/216312-help-with-php-that-reads-a-simple-xml-file/#findComment-1124174 Share on other sites More sharing options...
PFMaBiSmAd Posted October 20, 2010 Share Posted October 20, 2010 <?php // use OOP so that the call-back fucntions can share values // The real advantage of the xml_parser is that it parses the file line by line. This does however require that you "remember" // the current tag if you are not directly outputing content in order to associate the correct data with it class xml_class { private $parser; // instance of the xml_parser private $current = array(); // current set of values private $tag; // current tag function __construct(){ $this->parser = xml_parser_create(); xml_set_element_handler($this->parser, array('xml_class', 'start'),array('xml_class', 'stop')); xml_set_character_data_handler($this->parser, array('xml_class', 'char')); } function doit($file){ $fp=fopen($file,"r"); while ($data=fread($fp,4096)){ xml_parse($this->parser,$data,feof($fp)) or die (sprintf("XML Error: %s at line %d",xml_error_string(xml_get_error_code($this->parser)),xml_get_current_line_number($this->parser))); } xml_parser_free($this->parser); } function start($parser, $element_name, $element_attrs){ //echo 's' . $element_name . 's'; $this->tag = $element_name; // remember the current tag switch($element_name){ case "RED": // this is the start of a set of data $this->current = array(); // create an empty set break; default: } } function stop($parser, $element_name){ //echo 'e' . $element_name . 'e'; switch($element_name){ case "RED": // this is the tag that is after the end of the stated set of data, complete and execute the query here - // code to build the whole query statement and your mysql_query() goes here ... print_r($this->current); // contains the values for [TRIP], [PLATFORM], and [iNFORMATIONTYPE] echo "<br />"; break; default: } } function char($parser,$data){ $data = trim($data); if($data != ''){ $this->current[$this->tag] = $data; // echo "Tag: {$this->tag}, Value: $data<br />"; } } } // end of class $file = 'vehicle.xml'; $xml = new xml_class(); $xml->doit($file); ?> Quote Link to comment https://forums.phpfreaks.com/topic/216312-help-with-php-that-reads-a-simple-xml-file/#findComment-1124183 Share on other sites More sharing options...
BlueSkyIS Posted October 20, 2010 Share Posted October 20, 2010 would you recommend SimpleXML? http://php.net/manual/en/book.simplexml.php I was just recently tested in PHP and did poorly on a simple XML parsing test, as I have nearly no experience. Any insight is appreciated. Quote Link to comment https://forums.phpfreaks.com/topic/216312-help-with-php-that-reads-a-simple-xml-file/#findComment-1124186 Share on other sites More sharing options...
dpace32 Posted October 20, 2010 Author Share Posted October 20, 2010 <?php // use OOP so that the call-back fucntions can share values // The real advantage of the xml_parser is that it parses the file line by line. This does however require that you "remember" // the current tag if you are not directly outputing content in order to associate the correct data with it class xml_class { private $parser; // instance of the xml_parser private $current = array(); // current set of values private $tag; // current tag function __construct(){ $this->parser = xml_parser_create(); xml_set_element_handler($this->parser, array('xml_class', 'start'),array('xml_class', 'stop')); xml_set_character_data_handler($this->parser, array('xml_class', 'char')); } function doit($file){ $fp=fopen($file,"r"); while ($data=fread($fp,4096)){ xml_parse($this->parser,$data,feof($fp)) or die (sprintf("XML Error: %s at line %d",xml_error_string(xml_get_error_code($this->parser)),xml_get_current_line_number($this->parser))); } xml_parser_free($this->parser); } function start($parser, $element_name, $element_attrs){ //echo 's' . $element_name . 's'; $this->tag = $element_name; // remember the current tag switch($element_name){ case "RED": // this is the start of a set of data $this->current = array(); // create an empty set break; default: } } function stop($parser, $element_name){ //echo 'e' . $element_name . 'e'; switch($element_name){ case "RED": // this is the tag that is after the end of the stated set of data, complete and execute the query here - // code to build the whole query statement and your mysql_query() goes here ... print_r($this->current); // contains the values for [TRIP], [PLATFORM], and [iNFORMATIONTYPE] echo "<br />"; break; default: } } function char($parser,$data){ $data = trim($data); if($data != ''){ $this->current[$this->tag] = $data; // echo "Tag: {$this->tag}, Value: $data<br />"; } } } // end of class $file = 'vehicle.xml'; $xml = new xml_class(); $xml->doit($file); ?> Thank you for the quick reply - I tried this but it is still displaying all the data and now it is wrapping array around the output. I think this part is producing the output: function stop($parser, $element_name){ //echo 'e' . $element_name . 'e'; switch($element_name){ case "RED": // this is the tag that is after the end of the stated set of data, complete and execute the query here - // code to build the whole query statement and your mysql_query() goes here ... print_r($this->current); // contains the values for [TRIP], [PLATFORM], and [iNFORMATIONTYPE] echo "<br />"; break; default: } How do I filter this so it only shows where INFORMATIONTYPE = FAST and only display the Trip and the InformationType? Thank you again. Quote Link to comment https://forums.phpfreaks.com/topic/216312-help-with-php-that-reads-a-simple-xml-file/#findComment-1124197 Share on other sites More sharing options...
PFMaBiSmAd Posted October 20, 2010 Share Posted October 20, 2010 You would add a conditional statement to test the INFORMATIONTYPE element of the array - if($this->current['INFORMATIONTYPE'] == 'Fast'){ // process the data as needed... } Quote Link to comment https://forums.phpfreaks.com/topic/216312-help-with-php-that-reads-a-simple-xml-file/#findComment-1124198 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.