2

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

Calv
  • 133
  • 2
  • 11
  • You cannot change the content type in the midst of an HTML document. Are you trying to display *XML markup* or trying to use XML tags so that XML elements will be rendered somehow? Exactly how? XML elements have no default formatting (beyond being inline elements in the CSS sense). – Jukka K. Korpela Dec 04 '14 at 23:25
  • Trying to display XML markup so that its displayed within my page. I.E I can view the header, footer etc – Calv Dec 04 '14 at 23:37

3 Answers3

2

If you want markup to be displayed then change all < to &lt; and > to &gt;.

Before displaying anything load your XML to string variable and use this:

$before = array('<','>');
$after = array('&lt;','&gt;');
$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.

Forien
  • 2,712
  • 2
  • 13
  • 30
  • I've removed the header function and the XML now displays. However not in raw form which Id like. I don't fully understand your answer though as I'm no expert and still learning basics. – Calv Dec 04 '14 at 23:54
  • `<` in code shows in html page as `<`. So instead `$xmlobj=new SimpleXMLElement($_xml);` and latter calls paste my code and just change `$xml` in mine to yours `$_xml` – Forien Dec 04 '14 at 23:59
  • It is completely unnecessary to replace the “>” character. And in general it *is* necessary to replace the “&” character if it appears. – Jukka K. Korpela Dec 05 '14 at 09:17
-1
  1. You can use simplexml class to create XML nodes.
  2. If you want a raw XML you cannot use <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();
?>
Community
  • 1
  • 1
Grzegorz Krauze
  • 1,130
  • 12
  • 26
-1

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

  • escaping any occurrence of “<” as &lt;
  • escaping any occurrence of “&” as &amp;

For example, instead of

$_xml = '<?xml version="1.0" encoding="UTF-8"?>';

write

$_xml = '&amp;?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.

Jukka K. Korpela
  • 195,524
  • 37
  • 270
  • 390