Jump to content

help with PHP that reads a simple XML file


dpace32

Recommended Posts

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!  :D

-Adam

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

<?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);
?>

Link to comment
Share on other sites

<?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.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.