Page 1 of 1

Parsing XML with php 4

Posted: Wed Jul 18, 2007 7:32 am
by Jello
The code below is my attempt at parsing an XML document. Server is stuck on php4 so no SimpleXML for me :-(

It's pretty horrific really but as I'm the only one in the office this week who even knows what XML is and the client absolutely NEEDS it this week I had to bash this out. It works but I had one issue when writing it and I wonder if anyone can shed some light on it.

In the character data handler function for some reason I have to use the concatenate operator to get data into the array. When I used the assignment operator it didn't work at all. The array element was there but no data went into it.

What's causing that? Is it something to do with initialising variables?

Code: Select all

$phonesArr = array();
$item = 0;
$element = '';
$features = FALSE;
$featureNum = 0;
// Create an XML parser
$xml_parser = xml_parser_create();

xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");


$fp = fopen("file.xml","r")
       or die("Error reading XML data.");


while ($data = fread($fp, 4096))
   xml_parse($xml_parser, $data, feof($fp))
       or die(sprintf("XML error: %s at line %d",  
           xml_error_string(xml_get_error_code($xml_parser)),  
           xml_get_current_line_number($xml_parser)));

fclose($fp);
xml_parser_free($xml_parser);

//some whacky XML parsing functions using global vars...

function startElement($parser, $tagName, $attrs){

	global $phonesArr, $item, $element, $features, $featureNum;
	if($tagName == 'ITEM'){
	$item ++;	
	}
	if($tagName =='FEATURES'){
	$features = TRUE;
	}
	if($tagName =='FEATURE'){
	$featureNum ++;
	}
	$element = $tagName;
}
function endElement($parser, $tagName){
	global $features, $featureNum;
	if($tagName =='FEATURES'){
	$features = FALSE;
	$featureNum = 0;
	}
}
function characterData($parser, $data){
	global $phonesArr, $item, $element, $features, $featureNum;
	if($features==TRUE){
		$phonesArr[$item]['FEATURES'][$featureNum] .= $data;
	}else{
		$phonesArr[$item][$element] .= $data;
	}
}

Posted: Wed Jul 18, 2007 7:35 am
by dhrosti
I came across a similar situation a while ago. I used xml_parse_into_struct() to collect everything into arrays. i dont know much about parsing xml so im afraid thats all the help i can offer...

Posted: Wed Jul 18, 2007 7:41 am
by Jello
yeah xml_parse_into_struct() baffled me too much so I moved over to this approach.

It's my first(and hopefully last!) time using any of the XML functions normally just use simpleXML

Posted: Wed Jul 18, 2007 10:23 am
by volka
The cdata handler can be called more than once for one element.
E.g. because of entities that need to be resolved

Code: Select all

<?php
$xmlparser = xml_parser_create();
xml_set_character_data_handler($xmlparser, "characterData");
$xhtml = '<root>a"b</root>';

xml_parse($xmlparser, $xhtml, true);

function characterData($parser, $data) {
	echo '-', $data, '-';
}
-a--"--b-

as for the "Server is stuck on php4" part:
http://www.php.net/archive/2007.php#2007-07-13-1 wrote:The PHP development team hereby announces that support for PHP 4 will continue until the end of this year only.

Posted: Wed Jul 18, 2007 10:30 am
by Jello
Yeah tell me about it.. I'd be moving to php5 if I could but that means convincing my boss to let me spend time upgrading and debugging the server instead of earning money... which is short sighted I know....

Anyway cheers for the advice, it makes sense now!

Posted: Wed Jul 18, 2007 11:18 am
by volka
I'd try to play the "no support, no error fixes"-card in a way that it translates to "money loss" for your boss.