Forum Moderators: coopster

Message Too Old, No Replies

Php create XML file automatically

         

j milo taylor

8:22 pm on Mar 26, 2008 (gmt 0)

10+ Year Member



I have a MySql Php web app.

I can get XML output from database queries as part of mypage.php no problem.

Can I get Php to output this and save this data as a seperate .xml file in a specific directory ?

Thx
jmt

PHP_Chimp

9:27 pm on Mar 27, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Have a look at the file functions.

Specifically
fopen [uk3.php.net]
fwrite [uk3.php.net]


$fh = fopen('my_xml.xml', 'w');
fwrite($fh, $data);

There is a better example that includes checking that the file you are trying to write to is actually writable, and checking that the content is written in the fwrite manual page.

j milo taylor

11:26 pm on Mar 29, 2008 (gmt 0)

10+ Year Member



Hi PHP_Chimp,

Thanks for pointing me in the right direction.

Here comes the 'but' ;-)

I get this error

XML Parsing Error: junk after document element
Location: [XML_Artist_List.php...]
Line Number 241, Column 11:</artists>Success, wrote (<?xml version="1.0"?>

from this code:
-----
php connect to db etc>

$query = "SELECT * FROM artist WHERE year_artist <=1930 ORDER BY year_artist ASC";
$resultID = mysql_query($query, $linkID) or die("Data not found.");

$xml_output = "<?xml version=\"1.0\"?>\n";
$xml_output .= "<artists>\n";

for($x = 0 ; $x < mysql_num_rows($resultID) ; $x++){
$row = mysql_fetch_assoc($resultID);
$xml_output .= "\t<artist>\n";
$xml_output .= "\t\t<Artist_First_Name>" . $row['1stname_artist'] . "</Artist_First_Name>\n";
$xml_output .= "\t\t<Artist_Family_Name>" . $row['2ndname_artist'] . "</Artist_Family_Name>\n";

}

$xml_output .= "</artists>";

echo $xml_output;

-------(something wrong here?)

$filename = 'artists.xml';
if (is_writable($filename)) {
if (!$handle = fopen($filename, 'a')) {
echo "Cannot open ($filename)";
exit;
}
if (fwrite($handle, $xml_output) === FALSE) {
echo "Cannot write to ($filename)";
exit;
}
echo "Success, wrote ($xml_output) to ($filename)";
fclose($handle);
} else {
echo "The file $filename is not writable";
}
?>

So, they success echo $xml_output variable is not outputting the full content of the mysql query (should be a list of artists), and I dont get the 'junk after document element' message

Any ideas?
Cheers, Milo

PHP_Chimp

9:15 am on Apr 1, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The junk after document may well be because you will have something after the end of the xml...like another xml document.
Your xml is also not well formed. As you did not close the artist tag.

$xml_output = "<?xml version=\"1.0\"?>\n";
$xml_output .= "[b]<artists>[/b]\n";
for($x = 0 ; $x < mysql_num_rows($resultID) ; $x++){
$row = mysql_fetch_assoc($resultID);
$xml_output .= "\t[b]<artist>[/b]\n";
$xml_output .= "\t\t<Artist_First_Name>" . $row['1stname_artist'] . "</Artist_First_Name>\n";
$xml_output .= "\t\t<Artist_Family_Name>" . $row['2ndname_artist'] . "</Artist_Family_Name>\n";
// missing </artist>
$xml_output .= "\t</artist>\n";
}
$xml_output .= "</artists>";

As you are appending your code you will have multiple xml documents in the same file. So the first time you ran your code you got
<?xml version="1.0">
<artists>
<artist>
<Artist_First_Name>Some</Artist_First_name>
<Artist_Family_Name>Bloke</Artist_Family_Name>
</artist> <!-- well this wouldnt have been there -->
</artists>

The next time you run the code you get
<?xml version="1.0">
<artists>
<artist>
<Artist_First_Name>Some</Artist_First_name>
<Artist_Family_Name>Bloke</Artist_Family_Name>
</artist> <!-- well this wouldnt have been there -->
</artists>
<!-- this is the second run APPENDED -->
<?xml version="1.0">
<artists>
<artist>
<Artist_First_Name>Some</Artist_First_name>
<Artist_Family_Name>Bloke</Artist_Family_Name>
</artist> <!-- well this wouldnt have been there -->
<artist>
<Artist_First_Name>Some_1</Artist_First_name>
<Artist_Family_Name>Bloke_1</Artist_Family_Name>
</artist> <!-- well this wouldnt have been there -->
</artists>


As you are appending the information to the end of the file.

As your database will hold all of the up to date information you dont need to append the information. You will want to have a file that only contains that information, so just write to that file, not append.


[url=http://uk.php.net/manual/en/function.fopen.php]fopen[/url]($filename, 'w');

To test to see I my assumption is correct have a look at the content of your artists.xml. You can check to see if the xml is well formed and if you have multiple xml documents, within a single file.

j milo taylor

11:17 pm on Apr 3, 2008 (gmt 0)

10+ Year Member



hi chimp,

thanks for response:

1) for your 1st comment, perhaps there is something im missing, you wrote
'did not close the artist tag"

there is <b><artists></b> as root, then <i><artist></i> as child

so

$xml_output = "<?xml version=\"1.0\"?>\n";
$xml_output .= "<b><artists></b>\n";<b><----- open artists</b>
for($x = 0 ; $x < mysql_num_rows($resultID) ; $x++){
$row = mysql_fetch_assoc($resultID);
$xml_output .= "\t<i><artist></i>\n";<i><---- open artist</i>
$xml_output .= "\t\t<Artist_First_Name>" . $row['1stname_artist'] . "</Artist_First_Name>\n";
$xml_output .= "\t\t<Artist_Family_Name>" . $row['2ndname_artist'] . "</Artist_Family_Name>\n";
$xml_output .= "\t<i></artist></i>\n";<i><---- close artist</i>
}
$xml_output .= "<b></artists></b>";<---- <b>close artists</b>

so is this not correct?

2) the second observation - thankyou for pointing this out, it's helped a lot :-)

"fopen($filename, 'w');"

cheers,
m

j milo taylor

11:21 pm on Apr 3, 2008 (gmt 0)

10+ Year Member



hi chimp,

thanks for response:

1) for your 1st comment, perhaps there is something im missing, you wrote
'did not close the artist tag"

there is <artists> as root, then <artist> as child

so

$xml_output = "<?xml version=\"1.0\"?>\n";
$xml_output .= "<artists>\n";<----- open artists
for($x = 0 ; $x < mysql_num_rows($resultID) ; $x++){
$row = mysql_fetch_assoc($resultID);
$xml_output .= "\t<artist>\n";<---------- open artist
$xml_output .= "\t\t<Artist_First_Name>" . $row['1stname_artist'] . "</Artist_First_Name>\n";
$xml_output .= "\t\t<Artist_Family_Name>" . $row['2ndname_artist'] . "</Artist_Family_Name>\n";
$xml_output .= "\t</artist>\n";<---------- close artist
}
$xml_output .= "</artists>";<---- close artists

so is this not correct?

2) the second observation - thankyou for pointing this out, it's helped a lot :-)

"fopen($filename, 'w');"

cheers,
m

PHP_Chimp

12:46 pm on Apr 4, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



$xml_output = "<?xml version=\"1.0\"?>\n";
$xml_output .= "<artists>\n"; //Opened ARTISTS
for($x = 0 ; $x < mysql_num_rows($resultID) ; $x++){
$row = mysql_fetch_assoc($resultID);
$xml_output .= "\t<artist>\n"; //Opened ARTIST
$xml_output .= "\t\t<Artist_First_Name>" . $row['1stname_artist'] . "</Artist_First_Name>\n";
$xml_output .= "\t\t<Artist_Family_Name>" . $row['2ndname_artist'] . "</Artist_Family_Name>\n";
}
$xml_output .= "</artists>"; //Closed ARTISTS

I closed that tag in my post, however the quote above is from your original post and there doesnt seem to be an ending tag for artist.

So the </artists> will be junk, as that is an ending tag in the wrong place.
We tend to get lazy when coding HTML (or XHTML for those that use a mime type of text/html) as the browsers cover up our mistakes. However XML just doesnt work if it is not well formed, either through an error, misspelling, not closing a tag, or appending more xml document after the original document ;)

An easy way to check that your XML is valid is to look at it in something like Firefox, as Firefox will give you an error is the XML is not well formed. So you get the line number to make sorting the problem easier.