Page 1 of 1
SOLVED: parsing more than one xml file
Posted: Wed Aug 31, 2005 3:00 am
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???
Posted: Wed Aug 31, 2005 3:24 am
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'];
Posted: Wed Aug 31, 2005 3:39 am
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.
Posted: Wed Aug 31, 2005 4:01 am
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...
Posted: Wed Aug 31, 2005 4:32 am
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....
Posted: Wed Aug 31, 2005 5:11 am
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???
Posted: Wed Aug 31, 2005 7:05 am
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.
Posted: Wed Aug 31, 2005 7:20 am
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.
Posted: Wed Aug 31, 2005 7:23 am
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)));
}
}
}
Posted: Wed Aug 31, 2005 9:00 am
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();
?>