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);
Related
I am trying to create XML using DOMDocument from database table. All field types are showing in XML node except BLOB Type.
Below what I did:
$rs = ibase_query("SELECT * FROM mytable");
$coln = ibase_num_fields($rs);
$fieldnames = array();
for ($i = 0; $i < $coln; $i++) {
$col_info = ibase_field_info($rs, $i);
$fieldnames[] = array('name' => $col_info['name'], 'type' => $col_info['type']);
}
$doc = new DOMDocument('1.0');
$sth = ibase_query($dbh, $stmt);
$doc->formatOutput = true;
$root = $doc->createElement('FA_ARTIKEL');
$root = $doc->appendChild($root);
while ($row = ibase_fetch_object($sth, IBASE_TEXT)) {
$title = $doc->createElement('RECORD');
$title = $root->appendChild($title);
$text = $doc->createTextNode('');
$text = $title->appendChild($text);
foreach ($fieldnames as $value) {
switch ($value['type']) {
case 'VARCHAR':
$rtitle = $doc->createElement($value['name']);
$rtitle = $title->appendChild($rtitle);
$rtext = $doc->createTextNode($row->$value['name']);
$rtext = $rtitle->appendChild($rtext);
break;
case 'BLOB':
$rbtitle = $doc->createElement($value['name']);
$rbtitle = $title->appendChild($rbtitle);
$rbtext = $doc->createTextNode($row->$value['name']);
$rbtext = $rbtitle->appendChild($rbtext);
break;
default:
if ($row->$value['name']) {
$rtitle = $doc->createElement($value['name']);
$rtitle = $title->appendChild($rtitle);
$rtext = $doc->createTextNode($row->$value['name']);
$rtext = $rtitle->appendChild($rtext);
} else {
$rtitle = $doc->createElement($value['name']);
$rtitle = $title->appendChild($rtitle);
$rtext = $doc->createTextNode('0');
$rtext = $rtitle->appendChild($rtext);
}
break;
}
}
}
Header('Content-type: text/xml');
echo $doc->saveXML() . "\n";
ibase_free_result($sth);
ibase_close($dbh);
I tried with SimpleXMLElement also but it also failed. What I am missing?
My Database is Firebird and I set BLOB fields as
BLOB SUB_TYPE 1 SEGMENT SIZE 16384
PHPs DOMDocument expects UTF-8 strings. It is possible that the blob contains control characters/invalid unicode sequences. Try to put the data that breaks the XML into a variable and reduce your problem to the absolute minimum.
$blobData = $record['blobField'];
$document = new DOMDocument();
$document
->appendChild($document->createElement('foo'))
->appendChild($document->createTextNode($blobData));
echo $document->saveXml();
This way you can see if the blob data is really the problem or merely a symptom.
If the BLOB contains binary data you will need to convert it into a TEXT format. Atom feeds for example urlencode binary data that they want to embed. In this you will need to decode the value in the reading program.
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.
I've made this program that updates an xml file based on entries in an array.
I've used FILE_APPEND because the entries are more than one and otherwise file gets overwritten. But the problem is the xml version tag prints out as many times as many entries are there.
So i want to remove this tag.
Here's my program:-
<?php
include 'array.php';
$xmlW = new XMLWriter();
$file = 'entry-'. date('M-D-Y') .'.xml';
/*$setting = new XMLWriterSettings();
$setting->OmitXmlDeclaration = true;*/
foreach($data as $d) {
if(in_array ($d['Mode'], array('ccAV','MB','Paypal','E2P'))) {
$recordType = 'receipt';
$xml_object = simplexml_load_file ('receipt.xml');
} else {
$xml_object = simplexml_load_file ('journal.xml');
$recordType = 'journal';
}
$xml_object->xpath("/ENVELOPE/BODY/IMPORTDATA/REQUESTDATA/TALLYMESSAGE/VOUCHER")[0]->DATE = $d['InvoiceDate'];
$xml_object->xpath("/ENVELOPE/BODY/IMPORTDATA/REQUESTDATA/TALLYMESSAGE/VOUCHER")[0]->NARRATION = 'Rahul';
$xml_object->xpath("/ENVELOPE/BODY/IMPORTDATA/REQUESTDATA/TALLYMESSAGE/VOUCHER")[0]->EFFECTIVEDATE = $d['InvoiceDate'];
$xml_object->xpath("/ENVELOPE/BODY/IMPORTDATA/REQUESTDATA/TALLYMESSAGE/VOUCHER/ALLLEDGERENTRIES.LIST")[0]->LEDGERNAME = $d['Mode'];
$xml_object->xpath("/ENVELOPE/BODY/IMPORTDATA/REQUESTDATA/TALLYMESSAGE/VOUCHER/ALLLEDGERENTRIES.LIST")[0]->AMOUNT = 'Rahul';
$xml_object->xpath("/ENVELOPE/BODY/IMPORTDATA/REQUESTDATA/TALLYMESSAGE/VOUCHER/ALLLEDGERENTRIES.LIST")[1]->AMOUNT = 'Rahul';
$xml_object->xpath("/ENVELOPE/BODY/IMPORTDATA/REQUESTDATA/TALLYMESSAGE/VOUCHER/ALLLEDGERENTRIES.LIST")[2]->AMOUNT = 'Rahul';
$xml_object->xpath("/ENVELOPE/BODY/IMPORTDATA/REQUESTDATA/TALLYMESSAGE/VOUCHER/ALLLEDGERENTRIES.LIST/BANKALLOCATIONS.LIST")[0]->DATE = 'Rahul';
$xml_object->xpath("/ENVELOPE/BODY/IMPORTDATA/REQUESTDATA/TALLYMESSAGE/VOUCHER/ALLLEDGERENTRIES.LIST/BANKALLOCATIONS.LIST")[0]->INSTRUMENTDATE = 'Rahul';
$xml_object->xpath("/ENVELOPE/BODY/IMPORTDATA/REQUESTDATA/TALLYMESSAGE/VOUCHER/ALLLEDGERENTRIES.LIST/BANKALLOCATIONS.LIST")[0]->AMOUNT = 'Rahul';
$xml = $xml_object->asXML();
file_put_contents($file, $xml, FILE_APPEND);
}
?>
Thanks for the help.
I have a script that grabs an xml of my database generated by php and I would like to shuffle the rows before the php script echos the xml so that each time i access the database xml file, I'll receive the database in a different order.
here's part of my php script that outputs the xml:
$dom = new DOMDocument("1.0");
$node = $dom->createElement("database");
$parnode = $dom->appendChild($node);
$query = "SELECT * FROM database WHERE 1";
$result = mysql_query($query);
header("Content-type: text/xml");
while ($row = #mysql_fetch_assoc($result)){
// ADD TO XML DOCUMENT NODE
$node = dom->createElement("data");
$newnode = $parnode->appendChild($node);
$newnode->setAttribute("id", $row['id']);
$newnode->setAttribute("name", $row['name']);
$newnode->setAttribute("date", $row['date']);
$newnode->setAttribute("latitude", $row['latitude']);
$newnode->setattribute("longitude", $row['longitude']);
}
This is where I'd like to randomize the xml output if possible. This seems like the most logical place, but if there's a better place, that's fine with me.
echo $dom->saveXML();
Here's a sample of my xml:
<database>
<data id="1" name="blah" date="2012-10-10" latitude="0" longitude="0"/>
<data id="3" name="blah" date="2012-10-10" latitude="0" longitude="0"/>
<data id="4" name="blah" date="2012-10-10" latitude="0" longitude="0"/>
</database>
Simply put, I would like the xml rows to be in a different order each time i access it. Thanks for your help.
One way around this problem is to use a temporary array to store the rows fetched from DB, then shuffle this array, then walk through it:
$records = array();
while ($row = #mysql_fetch_assoc($result)){
$records[] = $row;
}
shuffle($records);
foreach ($records as $row) {
$node = dom->createElement("data");
$newnode = $parnode->appendChild($node);
$newnode->setAttribute("id", $row['id']);
...
}
The other way is use the original array as it is, but randomize the insertion process instead:
$prevnode = null;
while ($row = #mysql_fetch_assoc($result)){
$node = dom->createElement("data");
if ($prevnode && rand(0, 1) === 0) {
$newnode = $prevnode->insertBefore($node);
} else {
$newnode = $parnode->appendChild($node);
}
$prevnode = $newnode;
$newnode->setAttribute("id", $row['id']);
...
}
If your result set is not very large and your database supports it, you can have the database shuffle the results for you. For example, MySQL can do this:
SELECT * FROM database ORDER BY rand();
Your database may differ.
You could also separate XML generation from result collection. Shuffle the intermediate array:
function get_database_results($dbconn=null) {
$rows = false;
$query = 'SELECT * FROM database';
$res = mysql_query($query, $dbconn);
if ($res) {
$rows = array();
while ($row = mysql_fetch_assoc($res)) {
$rows[] = $row;
}
}
return $rows;
}
function array_to_sxe($rows) {
$sxe = simplexml_load_string('<database></database>');
foreach ($rows as $row) {
$data = $sxe->addChild('data');
foreach ($row as $key => $value) {
$data->addAttribute($key, $value);
}
}
return $sxe;
}
$rows = get_database_results();
shuffle($rows);
$sxe = array_to_sxe($rows);
header('Content-Type: application/xml'); // NOT text/xml!
echo $sxe->asXML();
I will now rant about encodings.
You have to be more careful about your encodings! As it is, you can very easily generate malformed XML.
text/xml means that the xml is in 7-bit ascii. That is very unlikely what you meant.
application/xml means that the xml is utf-8. This is what DOMDocument and SimpleXML output by default, and only accept utf-8 values for methods like setAttribute! This means you need to be absolutely sure:
That the strings you put into the database are utf-8.
That the connection between php and the database is utf-8. (Using SET NAMES utf8 or the charset parameter to the DSN with PDO--which you should be using instead of mysql_*)
That the strings you pull out of the database are utf-8, or at least are converted to utf-8 before use.
You can add
ORDER BY rand()
to your SQL-Query
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...