SOLVED: parsing more than one xml file

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
mat106
Forum Newbie
Posts: 16
Joined: Wed Aug 31, 2005 2:52 am

SOLVED: parsing more than one xml file

Post by mat106 »

Hello all. I have the following script that is meant to fetch the filenames of 5 xml files from a database and then parse them. The script will parse the first xml file fine but then returns the following error:
XML error: junk after document element at line 1
This is the script:

Code: Select all

$result = mysql_query("SELECT FILENAME FROM blog ORDER BY FILENAME DESC LIMIT 5");
		while ($row = mysql_fetch_array($result, MYSQL_BOTH))
			{
			$filename = "admin/$row[FILENAME]";
			if (!$fp = fopen($filename, "r")) {die ("Cannot open the file");}
			while ($data = fread($fp, 4096))
				{
				if (!xml_parse($xmlparser, $data, feof($fp)))
					{
					die (sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xmlparser)), xml_get_current_line_number($xmlparser)));
					}	
				}
			$currenttag = null;
			$name = null;
			$data = null;
			}
This is the structure of a typical xml file:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1"?>
<entry>
<year>2005</year>
<month>08</month>
<day>31</day>
<time>08:41:53</time>
<title>Some title</title>
<category>Some category</category>
<mainbody>Some text</mainbody>
</entry>
I've tried removing all whitespace from the xml files but still nothing. Any ideas on how to fix this???
Last edited by mat106 on Wed Aug 31, 2005 9:02 am, edited 1 time in total.
User avatar
n00b Saibot
DevNet Resident
Posts: 1452
Joined: Fri Dec 24, 2004 2:59 am
Location: Lucknow, UP, India
Contact:

Post by n00b Saibot »

Code: Select all

$filename = "admin/$row[FILENAME]";
I very much doubt this would fetch the filename...
it should be

Code: Select all

$filename = "admin/".$row['FILENAME'];
mat106
Forum Newbie
Posts: 16
Joined: Wed Aug 31, 2005 2:52 am

Post by mat106 »

n00b Saibot,

Both what i've got and what you recommend fetch the filename since, as i mentioned, the first xml file is parsed just fine. It's when it tries to parse a second xml file that the error occurs.
User avatar
n00b Saibot
DevNet Resident
Posts: 1452
Joined: Fri Dec 24, 2004 2:59 am
Location: Lucknow, UP, India
Contact:

Post by n00b Saibot »

If this is the case, well.. then the time is for a little basic debugging maybe... do a print_r() of the mysql_fetches and see if there is a problem...
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

xml files typically have one node...

If i get it right, your "xml" would look like:

<file1>
...
</file1>
<file2>
...
</file2>

As soon as the parser gets at </file1> it would expect that it's done.. And therefor says there is some junk....
mat106
Forum Newbie
Posts: 16
Joined: Wed Aug 31, 2005 2:52 am

Post by mat106 »

Thanks for you suggestions.

Each xml file is successfully fetched and assigined to $filename. It's also successfully opened and read using fread(). The problem occurs at the end with xml_parse($xmlparser, $data, feof($fp)).

timvm, I suspect the problem might be along the line of what you're saying but it doesn't actually make since for it to be so since i'm not joining the xml files into one $data variable. Nonetheless that's why i included:

Code: Select all

$currenttag = null;
$name = null;
$data = null;
but that didn't seem to solve the problem.

Any other ideas???
User avatar
n00b Saibot
DevNet Resident
Posts: 1452
Joined: Fri Dec 24, 2004 2:59 am
Location: Lucknow, UP, India
Contact:

Post by n00b Saibot »

In view of above comments and data being parsed correctly, the only one thing remains, and that is what timvw pointed to. each xml doc has one root element, beyond that xml is not valid.
So, i would suggest one thing now, it looks like you are creating xmlparser somewhere outside the loop. Move that to the start of loop and add a xml_parser_free() to the end of your loop. That should solve the problem hopefully.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

I seriously advise you to destroy the xml parser object every time once you read a XML file and recreate another to read a new XML file.
I had a similar problem but mine was implemented in OO.
viewtopic.php?t=37127&highlight=
http://raghavan20.allhyper.com/xmlParser.php (original file with the same error)
In my case, I had to unset the class object and recreate to read another file which I dont wanted to do but that was the only way it worked.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

not really so relevant but you should change from

Code: Select all

if (!$fp = fopen($filename, "r")) {die ("Cannot open the file");} 
            while ($data = fread($fp, 4096)) 
                { 
                if (!xml_parse($xmlparser, $data, feof($fp))) 
                    { 
                    die (sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xmlparser)), xml_get_current_line_number($xmlparser))); 
                    }     
                }

to

Code: Select all

if (!$fp = fopen($filename, "r")) {die ("Cannot open the file");} 
else{//look at the else here; you should read only if the $fp is not null
            while ($data = fread($fp, 4096)) 
                { 
                if (!xml_parse($xmlparser, $data, feof($fp))) 
                    { 
                    die (sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xmlparser)), xml_get_current_line_number($xmlparser))); 
                    }     
                } 
}
mat106
Forum Newbie
Posts: 16
Joined: Wed Aug 31, 2005 2:52 am

Post by mat106 »

At last it now works! The solution, as was pointed out, was that i had to destroy and recreate the parser for each file. This script now works:

Code: Select all

<?php
//if (!($xmlparser = xml_parser_create()))
//	{
//	die ("Cannot create parser");
//	}

function start_tag($xmlparser, $name, $attribs)
	{
	global $currenttag;
	$currenttag = $name;
	}

function end_tag($xmlparser, $name)
	{
	}
		
//xml_set_element_handler($xmlparser, "start_tag", "end_tag");

function tag_contents($xmlparser, $data)
	{
	global $currenttag;
	if ($currenttag == "TITLE") echo "<h3>".$data."</h3>";
	if ($currenttag == "MAINBODY") echo "$data";
	}
	
//xml_set_character_data_handler($xmlparser, "tag_contents");

require_once ("db_connect.php");

function run() 
	{
	//global $xmlparser;
	if (!empty($_GET['c']))
		{
		$category = $_GET['c'];
		$result = mysql_query("SELECT FILENAME FROM blog WHERE CATEGORY = '$category' ORDER BY FILENAME DESC");
		while ($row = mysql_fetch_array($result, MYSQL_BOTH))
			{
			if (!($xmlparser = xml_parser_create()))
				{
				die ("Cannot create parser");
				}
			xml_set_element_handler($xmlparser, "start_tag", "end_tag");
			xml_set_character_data_handler($xmlparser, "tag_contents");
			$filename = "admin/".$row['FILENAME'];
			if (!$fp = fopen($filename, "r")) {die ("Cannot open the file");}
			while ($data = fread($fp, 4096))
				{
				if (!xml_parse($xmlparser, $data, feof($fp)))
					{
					die (sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xmlparser)), xml_get_current_line_number($xmlparser)));
					}
				}
			xml_parser_free($xmlparser);
			}
		}
		else
		{
		$result = mysql_query("SELECT FILENAME FROM blog ORDER BY FILENAME DESC LIMIT 5");
		while ($row = mysql_fetch_array($result, MYSQL_BOTH))
			{
			if (!($xmlparser = xml_parser_create()))
				{
				die ("Cannot create parser");
				}
			xml_set_element_handler($xmlparser, "start_tag", "end_tag");
			xml_set_character_data_handler($xmlparser, "tag_contents");
			echo "$row[FILENAME]\n";
			$filename = "admin/".$row['FILENAME'];
			if (!$fp = fopen($filename, "r")) {die ("Cannot open the file");}
			while ($data = fread($fp, 4096))
				{
				if (!xml_parse($xmlparser, $data, feof($fp)))
					{
					die (sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xmlparser)), xml_get_current_line_number($xmlparser)));
					}	
				}
			$currenttag = null;
			$name = null;
			$data = null;
			xml_parser_free($xmlparser);
			}
		}
	}
run();
?>
Post Reply