Page 1 of 1

PHP Generated XML Problem

Posted: Thu May 24, 2007 3:15 am
by maddenuk
I'm using some AJAX logic to pull information out of the database and display that content on the basies of what a user chooses from a drop-down menu.

The PHP and Javascript works fine apart from the PHP generates invlaid XML and when i check the source code i can see it has genertaed a valid xml file except there is some white space before the xml declartion and i am not sure why? Can anyone help or give me some advice please?

Main Page: http://www.warwickwebvisions.com/calls-abroad/

PHP Page: http://www.warwickwebvisions.com/calls- ... ntry=india

The Error i get is:
This page contains the following errors:

error on line 1 at column 6: XML declaration allowed only at the start of the document
Below is a rendering of the page up to the first error.

Code: Select all

<?php 

header('Content-Type: text/xml'); 
require_once('error_handler.php'); 
require_once('classes/database.class.php'); 


$country = $_GET['country']; 
$table_id = 'country'; 
$connection = new database(); 
$link = $connection->database_connection(); 
$query = "select * from country where location ='$country'"; 
$results = mysql_query($query) or die(mysql_error()); 
if (!$results)     
    { 
        print 'There was a database error when executing'; 
        print mysql_error(); 
        exit; 
    } 
     
     
     
//create new xml document 
$doc = new DomDocument(); 


// create root node 
$root = $doc->createElement('response'); 
$root = $doc->appendChild($root); 

//process one row at a time 
while($row = mysql_fetch_assoc($results)) { 

//add node for each row 

$occ = $doc->createElement($table_id); 
$occ = $root->appendChild($occ); 

//add a child node for each field 
foreach ($row as $fieldname => $fieldvalue) { 

$child = $doc->createElement($fieldname); 
$child = $occ->appendChild($child); 

$value = $doc->createTextNode($fieldvalue); 
$value = $child->appendChild($value); 

    } //foreach 
} //while 

$xml_string = $doc->saveXML(); 

echo trim($xml_string); 

?>

Posted: Thu May 24, 2007 3:30 am
by volka

Code: Select all

<?xml version="1.0"?>
You have to remove all the spaces/tabs before <?xml

Posted: Thu May 24, 2007 4:20 am
by maddenuk
thanks for the reply i know thats what is causing it but i am unsure why a whitespace is occuring i have use the trim() as well to no sucess any ideas?

Cheers

Posted: Thu May 24, 2007 4:42 am
by volka
Check all <?php and ?> in country-find.php, error_handler.php and classes/database.class.php for leading and trailing tabs/spaces.

Posted: Thu May 24, 2007 5:10 am
by Maugrim_The_Reaper
Remove closing ?> tags on all files - they're not needed and this step automatically eliminates any whitespace at the end of a file (frequently after the closing tag) from being interpreted as output. I've stopped using the closing ?> and there is a noticeable lack of whitespace/output already sent type errors creeping into my code.

If you can't find the error quickly and it keeps dragging on, try using output buffering for that specific request (or other affected) so you can run trim() on the whole output and not just the part where you echo XML. That would basically be a band-aid - you still need to hunt down that bug to solve the root problem. Too many band aids just make your code unmaintainable over time.

Posted: Thu May 24, 2007 5:24 am
by volka
Maugrim_The_Reaper wrote:If you can't find the error quickly and it keeps dragging on, try using output buffering for that specific request (or other affected) so you can run trim() on the whole output and not just the part where you echo XML.
I would suggest the opposite approach: force a "header already sent" warning because it contains the location of the output

Code: Select all

<?php
ini_set('output_buffering', false);
ini_set('implicit_flush', true);

require_once('error_handler.php');
require_once('classes/database.class.php');

header('Content-Type: text/xml');

Posted: Thu May 24, 2007 8:47 am
by maddenuk
Thanks guys i have moved the site over to:

http://callsabroad.gb.com

http://callsabroad.gb.com/country-find. ... ntry=india

I've been able to remove the space thanks to your tips however it still says its an invalid xml file when you use the search tool?

Unsure why as it seems valid to me?

Code: Select all

<?xml version="1.0"?>
<response><country><id>1</id><location>India</location><content>Test Data for India</content></country></response>


Code: Select all

<?php 
ini_set('output_buffering', false); 
ini_set('implicit_flush', true); 


require_once('error_handler.php');
require_once('classes/database.class.php'); 

header('Content-Type: text/xml');

$country = $_GET['country'];
$table_id = 'country';
$connection = new database();
$link = $connection->database_connection();
$query = "select * from country where location ='$country'";
$results = mysql_query($query) or die(mysql_error());
if (!$results)	
	{
		print 'There was a database error when executing';
		print mysql_error();
		exit;
	}	
//create new xml document
$doc = new DomDocument();


// create root node
$root = $doc->createElement('response');
$root = $doc->appendChild($root);

//process one row at a time
while($row = mysql_fetch_assoc($results)) {


//add node for each row

$occ = $doc->createElement($table_id);
$occ = $root->appendChild($occ);

//add a child node for each field
foreach ($row as $fieldname => $fieldvalue) {

$child = $doc->createElement($fieldname);
$child = $occ->appendChild($child);

$value = $doc->createTextNode($fieldvalue);
$value = $child->appendChild($value);

	} //foreach
} //while

$xml_string = $doc->saveXML();

echo trim($xml_string);

Posted: Thu May 24, 2007 8:52 am
by volka
I don't get errors.

Posted: Sun May 27, 2007 1:30 pm
by maddenuk
thats strange when i go to http://callsabroad.gb.com and try and choose a destination this error pops up in a javascript alert box.
Error readin the response: Invlaid XML structure:
<?xml version="1.0"?>
</response>

Posted: Sun May 27, 2007 2:57 pm
by volka
<response />
i.e. the documentElement has no children. And that's why
//obtain the XML documents element
xmlRoot = xmlResponse.documentElement;

//testing that we received the XML document we expect
if(rootNodeName != "response" || !xmlRoot.firstChild)
throw("Invalid XML Structure:\n" + xmlHttp.responseText);
throws an exception.

Posted: Sun May 27, 2007 3:18 pm
by superdezign
This could just be me, but I'm against using PHP documents to generate XML within themselves when they need database interaction. It's way more querying than you need.

What you could try is to just use PHP to update them XML document once you've updated the content in the document, and only then. So, you'd use fopen, fwrite, and fclose. That's it. As long as you're familiar with how XML documents are created, you'd just make a string with all of these appropriate tags and loop through some database data, creating the items.

Maybe I haven't read carefully, enough, but this is the method I use. You give the file an '*.xml' extension and an XML header, and your server should automatically parse it as an XML file.

Posted: Sun May 27, 2007 3:53 pm
by volka
Welcome to the wonderful world of web 2.0 ;)