PHP XML error - extra content at the end of the document - php

I have the PHP code below, intended to create an XML document from 3 columns and multiple rows in an MySQL database. I am getting the following error message:
This page contains the following errors:
error on line 8 at column 11: Extra content at the end of the document
Below is a rendering of the page up to the first error.
-Some correct output as text.-
It drives me crazy, I have added and removed XML stuff in the code but nothing helps.
<?php
header('Content-type: text/xml');
$xmlout = "<?xml version=\"1.0\" ?>\n";
$xmlout .= "<TestXML>\n";
$db = new PDO('mysql:host=localhost;dbname=hidden','hidden','hidden');
$stmt = $db->prepare("SELECT * FROM testDB");
$stmt->execute();
while($row = $stmt->fetch()){
$xmlout .= "\t<test>\n";
$xmlout .= "\t\t<one>".$row['one']."</one>\n";
$xmlout .= "\t\t<two>".$row['two']."</two>\n";
$xmlout .= "\t\t<three>".$row['date1']."</three>\n";
$xmlout .= "\t</test>\n";
}
$xmlout .= "</TestXML>";
echo $xmlout;
?>
Help is very appreciated!

I would suggest using DOMDocument for the generation of XML rather than string concatenation. Depending upon the expected content you might also with to use CDATA sections to the XML - quite a simple modification to the code to allow that.
<?php
$sql='select * from `testdb`';
$db=new PDO('mysql:host=localhost;dbname=hidden','hidden','hidden');
$stmt=$db->prepare( $sql );
if( $stmt ){
$res=$stmt->execute();
if( $res ){
$dom=new DOMDocument;
$root=$dom->createElement('testXML');
$dom->appendChild( $root );
while( $rs=$stmt->fetch( PDO::FETCH_OBJ ) ){
$test=$dom->createElement('test');
$test->appendChild( $dom->createElement('one', $rs->one ) );
$test->appendChild( $dom->createElement('two', $rs->two ) );
$test->appendChild( $dom->createElement('three', $rs->three ) );
$root->appendChild( $test );
}
}
$stmt->closeCursor();
header('Content-Type: text/xml');
echo $dom->saveXML();
}
?>

Related

How can export mysql data in to xml using php

Below code is for export data from mysql table as xml file. I have tried several code but not getting the result. Please check and help me.
Currently getting result is
8sarathsarathernakulam423432washington9rahulrahulernakulam21212121newyork10aaaa3london11bbbb1newyork12cccc2washington13dddd3london
Code
<?php
require_once "classes/dbconnection-class.php";
if(isset($_POST['export'])){
header('Content-type: text/xml');
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
$root_element = "addressbook"; //fruits
$xml .= "<$root_element>";
$query = "SELECT AB.id, AB.name, AB.firstname, AB.street, AB.zipcode, AB.city_id, CI.city FROM address_book AS AB INNER JOIN city AS CI ON AB.city_id = CI.id";
$result = $mysqli->query($query);
if (!$result) {
die('Invalid query: ' . $mysqli->error());
}
while($result_array = $result->fetch_assoc()){
$xml .= "<address>";
foreach($result_array as $key => $value)
{
//$key holds the table column name
$xml .= "<$key>";
//embed the SQL data in a CDATA element to avoid XML entity issues
$xml .= "<![CDATA[$value]]>";
//and close the element
$xml .= "</$key>";
}
$xml.="</address>";
}
$xml .= "</$root_element>";
header ("Content-Type:text/xml");
//header('Content-Disposition: attachment; filename="downloaded.xml"');
echo $xml;
}
?>
Browser shows
<?xml version="1.0" encoding="UTF-8"?><addressbook><address><id><![CDATA[8]]></id><name><![CDATA[sarath]]></name><firstname><![CDATA[sarath]]></firstname><street><![CDATA[ernakulam]]></street><zipcode><![CDATA[42343]]></zipcode><city_id><![CDATA[2]]></city_id><city><![CDATA[washington]]></city></address><address><id><![CDATA[9]]></id><name><![CDATA[rahul]]></name><firstname><![CDATA[rahul]]></firstname><street><![CDATA[ernakulam]]></street><zipcode><![CDATA[2121212]]></zipcode><city_id><![CDATA[1]]></city_id><city><![CDATA[newyork]]></city></address><address><id><![CDATA[10]]></id><name><![CDATA[a]]></name><firstname><![CDATA[a]]></firstname><street><![CDATA[a]]></street><zipcode><![CDATA[a]]></zipcode><city_id><![CDATA[3]]></city_id><city><![CDATA[london]]></city></address><address><id><![CDATA[11]]></id><name><![CDATA[b]]></name><firstname><![CDATA[b]]></firstname><street><![CDATA[b]]></street><zipcode><![CDATA[b]]></zipcode><city_id><![CDATA[1]]></city_id><city><![CDATA[newyork]]></city></address><address><id><![CDATA[12]]></id><name><![CDATA[c]]></name><firstname><![CDATA[c]]></firstname><street><![CDATA[c]]></street><zipcode><![CDATA[c]]></zipcode><city_id><![CDATA[2]]></city_id><city><![CDATA[washington]]></city></address><address><id><![CDATA[13]]></id><name><![CDATA[d]]></name><firstname><![CDATA[d]]></firstname><street><![CDATA[d]]></street><zipcode><![CDATA[d]]></zipcode><city_id><![CDATA[3]]></city_id><city><![CDATA[london]]></city></address></addressbook>
When we are dealing with XML and HTML, the best way to act is ever through a parser.
In this particular situation, operating with a parser guarantees a valid XML and a clean, short code.
After defining mySQL query, we init a new DOMDocument with version and encoding, then we set his ->formatOutput to True to print out XML in indented format:
$query = "SELECT AB.id, AB.name, AB.firstname, AB.street, AB.zipcode, AB.city_id, CI.city FROM address_book AS AB INNER JOIN city AS CI ON AB.city_id = CI.id";
$dom = new DOMDocument( '1.0', 'utf-8' );
$dom ->formatOutput = True;
Then, we create the root node and we append it to DOMDocument:
$root = $dom->createElement( 'addressbook' );
$dom ->appendChild( $root );
At this point, after executing mySQL query, we perform a while loop through each resulting row; for each row, we create an empty node <address>, then we perform a foreach loop through each row's field. For each field, we create an empty childnode with tag as field key, then we append to childnode the field value as CDATA and the same childnode to <address> node; at the end of each while loop, each <address> node is appended to root node:
$result = $mysqli->query( $query );
while( $row = $result->fetch_assoc() )
{
$node = $dom->createElement( 'address' );
foreach( $row as $key => $val )
{
$child = $dom->createElement( $key );
$child ->appendChild( $dom->createCDATASection( $val) );
$node ->appendChild( $child );
}
$root->appendChild( $node );
}
Now, your XML is ready.
If you want save it to a file, you can do it by:
$dom->save( '/Your/File/Path.xml' );
Otherwise, if you prefer send it as XML you have to use this code:
header( 'Content-type: text/xml' );
echo $dom->saveXML();
exit;
If you want instead output it in HTML page, you can write this code:
echo '<pre>';
echo htmlentities( $dom->saveXML() );
echo '</pre>';
See more about DOMDocument
Go to your phpmyadmin database export and select xml in file format.
Replace
$xml .= "<![CDATA[$value]]>";
with
$xml .= $value;
IF you want to have it format it "nicely" in the browser add an:
echo "<pre>";
before the:
echo $xml;
Please note this WILL BREAK the XML file, but it will look good in the browser.... if that is what you are after...
I would suggest to use libraries like SimpleXMLElement etc. to create XML documents.
$xml = new SimpleXMLElement("<?xml version=\"1.0\" encoding=\"UTF-8\" ?><{$root_element}></{$root_element}>");
while($result_array = $result->fetch_assoc()){
foreach($result_array as $key => $value)
{
$address = $xml->addChild("address");
//embed the SQL data in a CDATA element to avoid XML entity issues
$addressFields = $address->addChild('"' . $key . '"', "<![CDATA[$value]]>");
//No need to close the element
}
}
Header('Content-type: text/xml');
print($xml->asXML());

Generating XML from SQL using Mysqli

I'm trying to pull all the data from my users table and display it in XML format. The connection works fine and everything as I have a login and registration set up fine, but I can't seem to get this to display anything other than a white screen.
I've found lots of different tutorials on how to do it with mysql but not mysqli. what am i missing?
generatexml.php
<?php
include 'connection.php';
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
$root_element = $config['users'];
$xml .= "<$root_element>";
if ($result = $mysqli->query("SELECT * FROM users", MYSQLI_USE_RESULT)) {
while($row = $result->fetch_assoc())
{
$xml .= "<".$config['users'].">";
//loop through each key,value pair in row
foreach($result_array as $key => $value)
{
//$key holds the table column name
$xml .= "<$key>";
//embed the SQL data in a CDATA element to avoid XML entity issues
$xml .= "<![CDATA[$value]]>";
//and close the element
$xml .= "</$key>";
}
$xml.="</".$config['users'].">";
echo $xml;
}
}
?>
I struggle a lot to find out this solution in mysqli format but nowhere i found the solution. Below is the solution i figured. Run this demo and map it your requirement, surely it will help.
<?php
//Create file name to save
$filename = "export_xml_".date("Y-m-d_H-i",time()).".xml";
$mysql = new Mysqli('server', 'user', 'pass', 'database');
if ($mysql->connect_errno) {
throw new Exception(sprintf("Mysqli: (%d): %s", $mysql->connect_errno, $mysql->connect_error));
}
//Extract data to export to XML
$sqlQuery = 'SELECT * FROM t1';
if (!$result = $mysql->query($sqlQuery)) {
throw new Exception(sprintf('Mysqli: (%d): %s', $mysql->errno, $mysql->error));
}
//Create new document
$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
//add table in document
$table = $dom->appendChild($dom->createElement('table'));
//add row in document
foreach($result as $row) {
$data = $dom->createElement('row');
$table->appendChild($data);
//add column in document
foreach($row as $name => $value) {
$col = $dom->createElement('column', $value);
$data->appendChild($col);
$colattribute = $dom->createAttribute('name');
// Value for the created attribute
$colattribute->value = $name;
$col->appendChild($colattribute);
}
}
/*
** insert more nodes
*/
$dom->formatOutput = true; // set the formatOutput attribute of domDocument to true
// save XML as string or file
$test1 = $dom->saveXML(); // put string in test1
$dom->save($filename); // save as file
$dom->save('xml/'.$filename);
?>
If you have access to the mysql CLI, here's my quick hack for achieving this:
$sql = "SELECT * FROM dockcomm WHERE listname = 'roortoor'
and status IN ('P','E') and comm_type IN ('W','O')
and comm_period NOT IN ('1','2','3','4') order by comment_num";
$cmd = "/usr/bin/mysql -u<person> -h<host> -p<password> <database> --xml -e \"$sql\";";
$res = system($cmd ,$resval);
echo $res;
Here is a solution using php only. You where close to getting it right. This was the key part of the code that I changed "$row as $key => $data" used $row instead of $result_array, ie. iterate through row not the result_array (this contains the entire dataset). Hope this helps someone.
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$value .="<record>\r\n";
//loop through each key,value pair in row
foreach($row as $key => $data)
{
//$key holds the table column name
$vals = "\t" . "<". $key . ">" . "<![CDATA[" . $data . "]]>" . "</" . $key . ">" . "\r\n";
$value = $value . $vals;
//echo $value;
}
$value .="</record>\r\n";
$count++;
}
} else {
// echo "0 results";
}
$conn->close();
One possible issue could be this line:
if ($result = $mysqli->query("SELECT * FROM users", MYSQLI_USE_RESULT)) {
Try the procedural approach instead of the object oriented approach. I do not know if $mysqli is defined in connection.php, but it is possible that you mixed it up.
if ($result = mysqli_query('SELECT * FROM users', MYSQLI_USE_RESULT)) {
This could resolve the white screen error.
I noticed two other things:
(1) One tiny effectiveness issue:
$xml = '<?xml version="1.0" encoding="UTF-8"?>';
So you do not need to escape every single quotation mark.
(2) One serious XML issue: The root element needs to be closed before you echo your $xml.
$xml .= "</$root_element>";
echo $xml;
Generally, for your purpose, it would be safer to use PHP's XMLWriter extension, as already proposed.

XMLWriter error on line 1 at column 1: Document is empty

i'm trying to get records from users table on MySQL, then save it on a randomly generated name xml file. so i have this code on my php:
<?php
include_once ("connect.php");
ini_set('max_execution_time', 300);
$length = 10;
$randomString = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, $length);
$savedstring = $randomString;
$sql = "SELECT * FROM users";
$query = mysql_query($sql);
$xml = new XMLWriter();
$xml->openURI($savedstring . '.xml');
$xml->startDocument("1.0");
$xml->setIndent(true);
$xml->startElement('users');
while ($row = mysql_fetch_assoc($query)) {
$xml->startElement("user");
$xml->writeAttribute('username', $row['username']);
$xml->writeRaw($row['password']);
$xml->endElement();
}
$xml->endElement();
header('Content-type: text/xml');
$xml->endDocument();
$xml->flush();
echo $savedstring;
?>
but it gets me error on line 1 at column 1: Document is empty, any hints on which part i'm doing it wrong? thanks in advance!
It would seem you're trying to write/read an empty XML document.
You can catch such an error with the following:
$xml = file_get_contents("/some/xml/file.xml");
if (trim($xml) == '') {
echo 'Empty XML file!';
}
$xml = simplexml_load_string($xml);

How to generate xml in codeigniter

I am trying to generate xml from database query.
Here is generated xml link: http://mydeal.ge/api/xml
But when I try to parse this xml, I get an error: http://wallsparade.com/test.php.
My code is:
public function xml()
{
$res = $this->db->query('custom query');
if($res->num_rows() > 0)
{$output = '<?xml version="1.0"?>'. "\n";
$output .= "<deals>";
foreach($res->result() as $item)
{
$output .= "<sale id = '".$item->id."'>";
$output .= "<link>".$item->link."</link>";
$output .= "<title>".urlencode($item->title)."</title>";
$output .= "<image>".$item->image."</image>";
$output .= "<text>".urlencode($item->text)."</text>";
$output .= "<time>".$item->time."</time>";
$output .= "<price>".$item->price."</price>";
$output .= "<parcent>".$item->parcent."</parcent>";
$output .= "</sale>";
}
$output .= '</deals>';
}
echo $output;
}
What is problem?
Looks like you are developing an API. Why don't you use the RESTServer plugin for CodeIgniter?
It's all handled for you and you don't have to worry about the format. You can choose to output in JSON or XML.
Plugin developed by Phil: https://github.com/philsturgeon/codeigniter-restserver
I believe the most practical, logical and error free way to generate an XML is to create a DOMDocument as suggested by Eineki in this answer, allowing the xmltree to be searched through an xpath query.
With this said, some years ago Dan Simmons created a single MY_xml_helper.php that you can just copy to your application/helpers folder directly. Here's the entire code without comments:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('xml_dom'))
{
function xml_dom()
{
return new DOMDocument('1.0', 'UTF-8');
}
}
if ( ! function_exists('xml_add_child'))
{
function xml_add_child($parent, $name, $value = NULL, $cdata = FALSE)
{
if($parent->ownerDocument != "")
{
$dom = $parent->ownerDocument;
}
else
{
$dom = $parent;
}
$child = $dom->createElement($name);
$parent->appendChild($child);
if($value != NULL)
{
if ($cdata)
{
$child->appendChild($dom->createCdataSection($value));
}
else
{
$child->appendChild($dom->createTextNode($value));
}
}
return $child;
}
}
if ( ! function_exists('xml_add_attribute'))
{
function xml_add_attribute($node, $name, $value = NULL)
{
$dom = $node->ownerDocument;
$attribute = $dom->createAttribute($name);
$node->appendChild($attribute);
if($value != NULL)
{
$attribute_value = $dom->createTextNode($value);
$attribute->appendChild($attribute_value);
}
return $node;
}
}
if ( ! function_exists('xml_print'))
{
function xml_print($dom, $return = FALSE)
{
$dom->formatOutput = TRUE;
$xml = $dom->saveXML();
if ($return)
{
return $xml;
}
else
{
echo $xml;
}
}
}
Notice that you set the encoding like this: new DOMDocument('1.0', 'UTF-8');. Here's an example:
$this->load->helper('xml');
$dom = xml_dom();
$book = xml_add_child($dom, 'book');
xml_add_child($book, 'title', 'Hyperion');
$author = xml_add_child($book, 'author', 'Dan Simmons');
xml_add_attribute($author, 'birthdate', '1948-04-04');
xml_add_child($author, 'name', 'Dan Simmons');
xml_add_child($author, 'info', 'The man that wrote MY_xml_helper');
xml_print($dom);
Would simply output:
<?xml version="1.0" encoding="UTF-8"?>
<book>
<title>Hyperion</title>
<author birthdate="1948-04-04">
<name>Dan Simmons</name>
<info>The man that wrote MY_xml_helper</info>
</author>
</book>
The xml_print either echos or returns the $xml->saveXML().
Notice: you can still use the one and only function from the default XML helper from CodeIgniter: xml_convert("<title>'Tom' & \"Jerry\"") which just outputs: <title>&apos;Tom&apos; & "Jerry".
Your XML document have to start with:
<?xml version="1.0"?>
no white symbols no "spaces" no "enters". Your document starts with line-break as the error message says:
Warning: simplexml_load_file() [function.simplexml-load-file]: http://mydeal.ge/api/xml:2: parser error : XML declaration allowed only at the start of the document in /home1/stinky/public_html/test.php on line 2
and delete spaces from this line:
$output .= "<sale id = '".$item->id."'>";
$output .= "<sale id='".$item->id."'>";
You shouldn't write XML through string concatenation when you have built-in library such as SimpleXMLElement available.
Try to change your code to this. I couldn't test it myself but it should work as expected:
<?php
public function xml()
{
$res = $this->db->query('custom query');
if ($res->num_rows() > 0) {
$sxe = new SimpleXMLElement();
$deals = $sxe->addChild('deals');
foreach($res->result() as $item) {
$sale = $deals->addChild('sale');
$sale->addAttribute('id', $item->id);
$sale->addChild('link', $item->link);
$sale->addChild('title', urlencode($item->title));
$sale->addChild('image', $item->image);
$sale->addChild('text', urlencode($item->text));
$sale->addChild('time', $item->time);
$sale->addChild('price', $item->price);
$sale->addChild('parcent', $item->parcent);
}
}
echo $sxe->saveXML();
}

using php to create an xml file from a mysql db

im trying to create a xml file using php.everytime i run the code the page displayes the code from a certain point as text on the screen.the code i hav is as follows:
<?php
if(!$dbconnet = mysql_connect('I took out the details')){
echo "connection failed to the host.";
exit;
}
if (!mysql_select_db('siamsati_db')){
echo "Cannot connect to the database.";
exit;
}
$table_id = 'events';
$query = "SELECT * FROM $table_id";
$dbresult = mysql_query($query, $dbconnect);
$doc = new DomDocument('1.0');
$root = $doc->createElement('root');
$root = $doc->appendChild($root);
while($row = mysql_fetch_assoc($dbresult)){
$ooc = $doc->createElement($table_id);
$occ = $root->appendChild($occ);
foreach ( $row as $fieldname => $fieldvalue){
$child = $doc->createElement($fieldname);
$child = $occ->appendchild($child);
$value = $doc->createTextNode($fieldvalue);
$value = $child->appendChild($value);
}
}
$xml_string = $doc->saveXML();
echo $xml_string;
?>
and the page when displayed shows:
createElement('root'); $root =
$doc->appendChild($root); while($row =
mysql_fetch_assoc($dbresult)){ $ooc =
$doc->createElement($table_id); $occ =
$root->appendChild($occ); foreach (
$row as $fieldname => $fieldvalue){
$child =
$doc->createElement($fieldname);
$child = $occ->appendchild($child);
$value =
$doc->createTextNode($fieldvalue);
$value = $child->appendChild($value);
} } $xml_string = $doc->saveXML();
echo $xml_string; ?>
is there something ive missed.ive checked all the quotes thinking it was that at first but they all seem to be right.any suggestions on what im doing wrong are much appreciated?
Set the content type to be XML, so that the browser will recognise it as XML.
header( "content-type: application/xml; charset=ISO-8859-15" );
In your code Change it to:
// Set the content type to be XML, so that the browser will recognise it as XML.
header( "content-type: application/xml; charset=ISO-8859-15" );
// "Create" the document.
$doc = new DOMDocument( "1.0", "ISO-8859-15" );
+++I think you can do something like this
<root>
<?
foreach ( $row as $fieldname => $fieldvalue){
?>
<events>
<fieldname><?=fieldname; ?></fieldname>
<fieldvalue><?=$fieldvalue; ?></fieldvalue>
</events>
}
?>
</root>
In the code you've posted here the initial <?php tag is missing...

Categories