I'm trying to display raw XML within HTML. If there's no HTML elements the XML displays fine However soon as I add my content, I am given this error
error on line 37 at column 6: XML declaration allowed only at the start of the document
After doing some research, the problem is common with having white spaces but I cant notice any. Heres my source code in question.
<?php require 'header.php'; ?>
<div class="sixteen columns">
<h3>XML</h3>
<?php
header("Content-Type:text/xml");//Tell browser to expect xml
include("config/init.php");
$connection = mysqli_connect($hostname, $username, $password, $databaseName) or die("you did not connect");
$query = "SELECT * FROM art";
$result = mysqli_query($connection, $query) or die (mysqli_error($connection));
//Top of xml file
$_xml = '<?xml version="1.0" encoding="UTF-8"?>';
$_xml .="<art>";
while($row = mysqli_fetch_array($result)) {
$_xml .="<art>";
$_xml .="<art_name>".$row['name']."</art_name>";
$_xml .="<art_category>".$row['category']."</art_category>";
$_xml .="<art_price>".$row['price']."</art_price>";
$_xml .="</art>";
}
$_xml .="</art>";
//Parse and create an xml object using the string
$xmlobj=new SimpleXMLElement($_xml);
print $xmlobj->asXML();
$xmlobj->asXML('art.xml');
?>
</div>
<?php require 'footer.php'; ?>
http://www.acalvert.x10host.com/xml.php If you wish to view page source
If you want markup to be displayed then change all <
to <
and >
to >
.
Before displaying anything load your XML to string variable and use this:
$before = array('<','>');
$after = array('<','>');
$xml = str_replace($before,$after,$xml);
echo $xml;
Secondly - you cannot call header()
function after displaying ANY character. Don't use it at all. You want default text/html
in your document.
<div class="sixteen columns"><h3>XML</h3>
and </div>
. You have to decide if you want XML or HTML output.Here is how you use SimpleXMLElement to create and print the XML output:
How to write CDATA using SimpleXmlElement?
In your case it will be:
<?php
class SimpleXMLExtended extends SimpleXMLElement {
public function addCData($cdata_text) {
$node = dom_import_simplexml($this);
$no = $node->ownerDocument;
$node->appendChild($no->createCDATASection($cdata_text));
}
}
$docXML = new SimpleXMLExtended("<art/>");
while($row = mysqli_fetch_array($result)) {
$nodeXML0 = $docXML->addChild("art");
$nodeXML01 = $nodeXML0->addChild("art_name");
$nodeXML01->addCData($row['name']);
$nodeXML02 = $nodeXML0->addChild("art_category");
$nodeXML02->addCData($row['category']);
$nodeXML03 = $nodeXML0->addChild("art_price");
$nodeXML03->addCData($row['price']);
}
Header('Content-type: text/xml');
echo $docXML->asXML();
?>
When you want to show XML markup as text (as you clarify in a comment), not interpreted as tags, you simply need to do the same as when showing HTML markup as text inside an HTML document. This means
<
&
For example, instead of
$_xml = '<?xml version="1.0" encoding="UTF-8"?>';
write
$_xml = '&?xml version="1.0" encoding="UTF-8"?>';
In addition, you need to remove the lines
header("Content-Type:text/xml");//Tell browser to expect xml
because you are generating a response body already and cannot inject any HTTP headers.
There is a way to tell browsers that markup be displayed as-is and not interpreted: wrap it between the tags <xmp>
and </xmp>
. The xmp
element has been in HTML implementations from the beginning, but it has for a long time been declared deprecated/obsolete. It still works, and it also causes the source formatting with regard to line breaks and spaces to be preserved.