I'm trying to generate an XML output with Zend_Framework, but this nasty thing keeps popping up:
XML Parsing Error: XML or text declaration not at start of entity
Location: http://cart/index/kurpirkt
Line Number 2, Column 1:<?xml version="1.0" encoding="utf-8"?>
^
As far as I know there are no white-spaces in any of my include files, and even if there were, I think that the ob_clean() function should have taken care of it. Here is my code:
public function kurpirktAction()
{
ob_clean();
// XML-related routine
$xml = new DOMDocument('1.0', 'utf-8');
$xml->appendChild($xml->createElement('foo', 'bar'));
$output = $xml->saveXML();
// Both layout and view renderer should be disabled
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer')->setNoRender(true);
Zend_Layout::getMvcInstance()->disableLayout();
// Setting up headers and body
$this->_response->setHeader('Content-Type', 'text/xml; charset=utf-8')
->setBody($output);
}
Any help or suggestions?
First test, if the additional whitespace occures in all actions of your application.
If so, check
/public/index.php and
/application/bootstrap.php
for trailing spaces before <?php or old left-over debug statements.
Edit: transfered the helpful information from the comments to the answer
Related
I'm extracting data from MySQL into flash. First I use PHP to query the DB, and then I echo the results.
$sql = "SELECT path FROM video WHERE id = 52";
$resource = mysqli_query($conn,$sql);
$row = mysqli_fetch_assoc($resource);
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
echo "<video>\n";
echo "<path>" . $row['path'] . "</path>\n";
echo "</video>\n";
I only have one root element, and I don't see anything wrong with my markup following the root element...but then again I'm wrong and I'm sure there is an error.
--- Changed my Title so I added the error message here ---
TypeError: Error #1088: The markup in the document following the root element must be well-formed.
------EDITED ------
The value of $row['path'] is a string from my DB. I know it's valid because I deleted all xml tags and echoed $row['path'] which is the url path for the video. I also used gettype(), and it outputs a string.
When I open this file into my browser, I actually don't see anything. It's a blank page, but it's because the browser is rendering it as html elements, so I don't think that's the problem. But when I view source, I get this
<?xml version="1.0" encoding="UTF-8"?>
<video>
<path>1.mp4</path>
</video>
In addition, I created a random file with an xml extension with the xml contents above, (copied it form View Source that my php file outputs) and it works fine. I see the contents in Flash. What could be wrong with echoing it out in a php file? I'm using textWrangler. It might have something to do with BOM, any suggestions?
----EDIT NUMBER TWO ---
Here's my actionscript code. I'm still new so I didn't put it in a class but inside the first frame in my actions layer. I'm just trying to get the basics to work.
var theXML:XML;
var xmlReq:URLRequest = new URLRequest("../folderExample/poop.php");
var xmlLoader:URLLoader = new URLLoader();
function xmlLoaded(event:Event):void{
theXML = new XML(xmlLoader.data); // The Error occurs here.
trace(theXML.toXMLString());
}
xmlLoader.load(xmlReq);
xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded);
From http://www.flashdevelop.org/community/viewtopic.php?f=13&t=3128
For well-formed XML returning
TypeError: Error #1088: The markup in the document following the root element must be well-formed,
often the problem is the BOM.
Actionscript XML does not strip the BOM (Byte Order Mark) from incoming text. The BOM is an invisible character (#65279) created at the beginning of a ASP or php "echo" string, as well as some text editors, to indicate the byte-ordering of multibyte text.
You can confirm if your string has this BOM character like this:
trace( sXMLString.charCodeAt( 0 ) ); //outputs 65279
The quick solution is
sXMLString= sXMLString.replace( String.fromCharCode(65279), "" ) ;
myXML = new XML(sXMLString);
See also:
Reading php generated XML in flash?
How to load PHP dynamically generated XML in FLASH
If you don't have it already, from the second link above, try adding:
header("Content-Type: text/xml");
I implemented a basic mvc framework in php. The problem is that when I want to create a dynamic kml file not open, because the file at the start of blank spaces are generated. If I do it from any file (not the framework), it works correctly.
Link :localhost/Radio/index/asset
Controller : indexController.php
method : asset()
code:
public function asset() {
$dom = new DOMDocument('1.0', 'UTF-8');
$kmlOutput = $dom->saveXML();
$kmlOutput = trim($kmlOutput);
header('Content-type: application/vnd.google-earth.kml+xml');
header('Content-disposition: attachment; filename="myfilename.kml"');
echo $kmlOutput;
}
error in Google Earth :
kml generate:
Thanks in advance.
Blanks at the beginning of the output are often caused by newlines behind the closing php tag.
<?php¶
¶
// Some code here¶
¶
?>¶
¶
Anything outside of <?php ?> as directly seen as output. Therefor, you should never use the closing tag in library files.
To quote Zend Framework:
For files that contain only PHP code, the closing tag ("?>") is never
permitted. It is not required by PHP, and omitting it´ prevents the
accidental injection of trailing white space into the response.
I have this code :
$xml = new SimpleXMLElement('<myxml></myxml>');
$xml->addChild('testNode attr="test Attribute"');
$node = $xml->addChild('erroNode attr="My Child node causes error -> expect >"');
//$node->addChild('nodeChild attr="node Child"');
header('Content-type: text/xml');
echo $xml->asXML();
exit();
I can create a childnode with attributes via $xml, but not with $node(child's child), Why? i get the error error on line 2 at column 66: expected '>'
From the docs it say that the addChild function returns a SimpleXmlElement of the child.
Check by uncommenting the commented line $node->addChild('nodeChild attr="node Child"');
Also it only happens when header is sent, if i comment header and do like below i can see the correct xml in page source :
$xml = new SimpleXMLElement('<myxml></myxml>');
$xml->addChild('testNode attr="test Attribute"');
$node = $xml->addChild('erroNode attr="My Child node causes error -> expect >"');
$node->addChild('nodeChild attr="node Child"');
//header('Content-type: text/xml');
echo $xml->asXML();
exit();
My PHP version is 5.4.9
The error you are seeing is not coming from SimpleXML, but from your browser - that's why changing the HTTP header works. With this line, the browser knows the page is XML, and checks that it's valid; without it, it assumes it's HTML, and is more lenient:
header('Content-type: text/xml');
If you use "View Source" in your browser, you'll find that the actual output from PHP is the same in both cases. Another nice test is to set the content-type to text/plain instead, which means the browser won't interpret the output at all, just show it as-is.
So, for some reason, SimpleXML is generating invalid XML. This is because the ->addChild() method takes as its first argument just the name of the element to add, in your case 'erroNode'; you are passing in an invalid name that also includes attributes, which should be added later with ->addAttribute().
If we simplify the example a bit further, and look at the XML generated, we can see what's going on (here's an online demo):
// Make browser show plain output
header('Content-type: text/plain');
// Working example
$xml = new SimpleXMLElement('<myxml></myxml>');
$xml->addChild('testNode attr="test Attribute"');
echo $xml->asXML();
echo "\n";
// Broken example
$xml = new SimpleXMLElement('<myxml></myxml>');
$node = $xml->addChild('testNode attr="test Attribute"');
$node->addChild('test');
echo $xml->asXML();Child('testNode attr="test Attribute"');
$node->addChild('test');
echo $xml->asXML();
This outputs the below:
<?xml version="1.0"?>
<myxml><testNode attr="test Attribute"/></myxml>
<?xml version="1.0"?>
<myxml><testNode attr="test Attribute"><test/></testNode attr="test Attribute"></myxml>
The first version of the XML appears to be doing the right thing, because it has created a "self-closing tag". However, in the second, you can see that SimpleXML thinks that the tag name is 'testNode attr="test Attribute"', not just 'testNode', because that's what we told it.
The result is that it tries to put a closing tag with that "name", and ends up with </testNode attr="test Attribute">, which isn't valid XML.
Arguably, SimpleXML should protect you against this kind of thing, but now that you know, you can easily fix the code (demo):
// Make browser show plain output
header('Content-type: text/plain');
// Fixed example
$xml = new SimpleXMLElement('<myxml></myxml>');
$node = $xml->addChild('testNode');
$node->addAttribute('attr', 'test Attribute');
$node->addChild('test');
echo $xml->asXML();
Now, SimpleXML knows that the tag is just called 'testNode', so can create the correct closing tag when it needs to:
<?xml version="1.0"?>
<myxml><testNode attr="test Attribute"><test/></testNode></myxml>
I am generating php page using smarty template based on html form input and uploaded files. Using dompdf, I want to save the generated page as a pdf file.
When the user submits the multipart/form-data, data is posted to itself. Then it undergoes validation process. When all is fine, a new page is generated using a template file. There is no output, instead, dompdf utilizes the template file to stream the pdf file. After solving several stages of problems such as "DOMPDF not found", insufficient memory etc, I am now stuck with "Unable to stream pdf: headers already sent" error.
One of the most common problems is presence of line break, white space or any output being before stream() is called. I checked for white space before and after <?php and >?.
There are nor print_f or echo statements either. How can I troubleshoot this problem? Where does the problem lie...in the smarty template file or the php file itself?
Here is the code:
require_once("dompdf/dompdf_config.inc.php");
spl_autoload_register('DOMPDF_autoload');
$html = $smarty->fetch('index.tpl');
$dompdf = new DOMPDF();
$dompdf->load_html($html);
$dompdf->set_paper('a4', 'portrait');
$dompdf->render();
$dompdf->stream("newfile.pdf");
simple solution :
write below lines before stream, it will show where exactly new line or space is coming
$f;
$l;
if(headers_sent($f,$l))
{
echo $f,'<br/>',$l,'<br/>';
die('now detect line');
}
I had the same problem, and I solved this problem by adding this code in the top file:
ob_start();
Most probably there's a whitespace or new line somewhere in your code causing this. Here's a simple way to debug it:
echo something at the very end of your script (above the stream() call), for example echo "end!";exit;
Click to "view source" of your page, which makes spaces easier to see
If your "end!" string does not appear at the very start of your script, then somewhere there's a character printed
Move the "echo end!" line further up to your code, until you locate where the space was inserted
Another possibility is that you are using a language string somewhere that introduces an unprintable character. If your application is multilingual, make sure you're testing using english
Replace line 3105 of this file: dompdf/lib/class.pdf.php
if ( headers_sent()) {
die("Unable to stream pdf: headers already sent");
}
With
$output = ob_get_clean();
if ( headers_sent()) {
echo $output; }
Then in the file that is generating the pdf output e.g if you were outputting from a Joomla Component
components/com_joomlacomponent/views/yourpdfdir/tmpl/default.php
Enter immediately after the opening php tag
<?php
ob_start();
I tried to echo out, but no white spaces or line breaks were found. At the end, I redirected the php to another page instead of PHP_SELF and the problem vanished. I did not alter any code. Looks like presence of html tags after the php ended was the offending factor.
Be sure your editor does not add a Unicode Bom description - save code to file by Notepad, or (if you work in Dreamweaver) remove check by Asign Unicode Signature (BOM) or something. ;)
I came across this issue. You want to check all the variables you are using.
One or even more than one variable you are passing comes empty and is messing the render.
Start gradually, by getting rid of all the php and try to generate the pdf, then if it works for you add code block by block.
This will help you identify where the problem is.
I had this issue, with no apparent output when viewing the source. The problem for me was that I had flushed the output, even though there was none except the headers, and that blocked streaming the output giving the "headers already sent" message. Which was true. My fix was to remove the flush() and ob_flush() statements, and the streaming output then worked.
for me - solution was to encode my file to UTF-8 instead of UTF-8 BOM
In my case the problem was solved by setting $_dompdf_show_warnings to false in dompdf_config_inc.php
I'm using the header() function to turn a file into XML standard.
The problem is when I use <?php header("Content-type: text/xml; charset=utf-8"); ?> it just renders the <?xml version="1.0"?>, without the enconding/charset. Am I using it wrongly?
The header() function just modifies HTTP headers. The code you posted sets a Content-Type header, which is important for telling browsers and other clients what type of file you're serving.
The <?xml version="1.0"?> line you're talking about is part of the document itself, and not affected by the HTTP headers.
Your tags say you're using DOM to create your XML document. If you change your DomDocument constructor to also pass the charset,
$doc = new DomDocument('1.0', 'UTF-8');
It should output that charset in the XML document.
header just sets a HTTP header in the result. PHP doesn't do anything else with the value, so it's up to you to make sure it's being used properly.
If you're using an XML library to generate your XML (including the prologue), check the documentation for that library. If you're outputting the XML "by hand" (o, you need to add the necessary attribute to the prologue yourself.
You can also use
<?php echo '<?xml version"1.0" encoding="UTF-8"?>'; ?>