PHP -> XML output is different on IE - php

I have been trying to output XML with PHP but encountered a strange(!) error in Internet Explorer.
The expected xml output is this:(simplified)
<root>
<match_id>12</match_id>
<stadium_id>43</stadium_id>
<tribune_id>2</tribune_id>
<fan_id>453</fan_id>
</root>
I am producing this output with the following PHP code:
echo "<?xml version='1.0' encoding='utf-8' ?>
<root>
<match_id>"; echo $match->getId(); echo "</match_id>
<stadium_id>43</stadium_id>
<tribune_id>2</tribune_id>
<fan_id>".$_SESSION['user_id']."</fan_id>
</root>";
In Firefox, the output is same as expected. However, in IE, the output is this:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<match_id>0</match_id>
<stadium_id>43</stadium_id>
<tribune_id>2</tribune_id>
<fan_id />
</root>
This is a really annoying error. I have set the PHP header for XML output, and changed lots of other things but could not make it work.
The $match->getId() part is just returning an integer but IE always shows this value as 0. If I set <fan_id> and <match_id> manually, IE shows the values correctly.
By the way, I am using this XML output in Flash (AS3) and this also shows the same result with IE.
What am I doing wrong?

This looks like it's due to a session difference - the IE session isn't storing the user id. Similarly, $match->getId() is actually 0 - I imagine you'd get a similar result using Chrome or Safari or a web browser on any other computer.
One other thing: Flash may not be sending the PHP session cookie to the server on the request - which would match the IE behavior / no valid session.

Try:
header( "content-type: application/xml; charset=ISO-8859-15" );
OR
$doc = new DOMDocument;
$root = $doc->createElement('root');
$doc->appendChild($root);
$match_id = $doc->createElement('match_id', $match->getId());
$root->appendChild($match_id);
$stadium_id = $doc->createElement('stadium_id', '43');
$root->appendChild($stadium_id);
$tribune_id = $doc->createElement('tribune_id', '2');
$root->appendChild($tribune_id, '2');
$fan_id = $doc->createElement('fan_id', $_SESSION['user_id']);
$root->appendChild($fan_id);
echo $doc->saveXML();
//$doc->save('file.xml'); // if you want to write to file

What browser is used has no effect on how your PHP executes (because it's executed on server, not in browser). Notice that in the second example your fan_id is also empty, which indicates something's wrong with your session setup. Investigate this.
Having said all that: did you consider using simplexml() to output XML from PHP? It's much more fun to use than echoing tags.

Related

How can I load POST data into SimpleXML?

I need to post XML data from a textarea input to PHP so I can parse it and output a table.
I've tried a few methods and none seem to be working.
Currently I have this:
jQuery('#btnRegistrarXML').live('click', function(){
var xml;
if (jQuery('#txtRegXML').val() == ""){
AddMsg('You must paste XML from the excel export into the textarea.', 'error');
} else {
jQuery.post('registrar-xml-to-table.php', {xml:escape(jQuery('#txtRegXML').val())}, function(data){
jQuery('#regXMLasTable').empty();
jQuery('#regXMLasTable').append(data);
});
}
displayMsgs();
});
The PHP is:
$xmlraw = urldecode($_POST['xml']);
$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->loadXML($xmlraw);
$dom->formatOutput = TRUE;
$xmlstr = $dom->saveXml();
$xml = simplexml_load_string($xmlstr);
echo "<p>xmlraw:</p>";
echo $xmlraw;
echo "<p>xml:</p>";
echo $xml;
foreach ($xml->document as $doc) {
echo '<p class="alert alert-error">'.$doc->title.'</p>';
}
The first echo $xmlraw is working - it outputs the XML string all on one line - the post is sending the data through properly.
The second echo $xml doesn't output anything and the foreach doesn't output anything either - something is not working in the PHP
I've also tried loading $xmlraw directly into simplexml_load_string($xmlraw) but it doesn't work - I'm assuming because it's not well formed?
The XML I'm using to test is:
<?xml version="1.0"?>
<document>
<title>
Foobar
</title>
</document>
You can paste the XML into the textarea on this ( http://tsdexter.com/webservice-testing/programs-list.php ) page and then if you inspect element underneath xmlraw: you can see that the raw xml string was echoed - however, underneath xml: there is nothing and also the foreach doesn't output anything either.
Here's a jsFiddle so you can see the HTML/JS - it doesn't actually do anything though because it can't ajax to the PHP page - so I included the PHP version above to test. http://jsfiddle.net/tsdexter/EDqQB/
Any ideas?
A few questions, which may or may not constitute an answer, but needed more space than a comment.
Why are you running urldecode on the $_POST variable? PHP should be doing that for you, unless you are double-escaping it somewhere.
Why are you loading into DOM and then SimpleXML? I know you said you tried without, but they use the same XML parser underneath, so there is no way this will help you rather than introducing more confusion.
What does var_dump(simplexml_load_string($rawxml)) give you? My guess would be FALSE, meaning an error. In which case, check you have warnings turned on (error_reporting(E_ALL); ini_set('display_errors', '1');) and detailed XML error handling turned off (libxml_use_internal_errors(false);).
In case it does give you a SimpleXMLElement object, don't spend too long looking at the var_dump output. Try one of these debugging functions instead.

Php adding xml for no reason

I am calling a database query and using a foreach loop to display results, however it is causing a W3C error and on inspection I have found that it is adding '<?xml version="1.0" encoding="UTF-8"?>' to my first echo...I have no idea why?? I have moved my php from the very top of the file to the body but still the same problem :(
Can someone help me?
Where are you seeing the <xml ... > header? Note that if you are viewing this in the browser source, the browser will generally automatically add this if the doctype is XHTML.

Unable to export XML from PHP using WAMPServer

I am using WAMPServer 2.1 on my local machine. I am trying to create a simple PHP script to output an XML file. I cannot get it to work without generating an error on IE and Chrome. On Firefox 4, it works.
Here is the PHP:
<?php
main();
function main()
{
header("Content-type: application/xml");
OutputXML('xml/login_user_good.xml');
exit(0);
}
function OutputXML($filename)
{
echo file_get_contents($filename);
}
?>
Here is the XML file:
<?xml version="1.0" encoding="utf-8" ?>
<login_user>
<result_code value="1"/>
<error value="Invalid username or password"/>
</login_user>
When I tried to access my PHP script using IE 8, I get this error:
The XML page cannot be displayed Cannot view XML input using style sheet.
Please correct the error and then click the Refresh button, or try again later.
--------------------------------------------------------------------------------
Invalid at the top level of the document. Error processing resource
'http://localhost/kiamobile/login_user.php'. Line 1, P...
<?xml version="1.0" encoding="utf-8" ?>
^
On Google Chrome 10, I get this error:
This page contains the following errors:
error on line 1 at column 6: XML declaration allowed only at the start of the document
On Firefox 4, I get a properly formatted XML output.
On any of the browsers, when I View Source, I can see the correct XML.
I have tried with and without the explicit header. If I remove the call to the PHP header() function, I get these results:
IE 8: Same error as before
Firefox 4: Blank screen
Chrome 10: Blank screen
Again, if I View Source in any of the browsers, I can see the XML. I have tried using text/html instead of application/xml, with no effect.
I have tried generating the XML directly in the PHP code, like this:
<?php
main();
function main()
{
header("Content-type: application/xml");
OutputXML();
exit(0);
}
function OutputXML()
{
echo <<<END
<?xml version="1.0" encoding="utf-8" ?>
<login_user>
<result_code value="1"/>
<error value="Invalid username or password"/>
</login_user>
END;
}
?>
When I do this, I get these results:
IE 8: Same error
Firefox 4: I see the formatted XML
Chrome 10: Blank screen
What am I doing wrong?
Your script may contain unwanted and invisible chars (like BOM) before PHP start tag
Browsers are not made for displaying just any arbitrary XML. They like HTML (which can be XHTML). It is unclear why you want browsers to display those. If it is intended for an and user then you should format those in HTML, if it is for a API (service) then check it with curl/wget/etc and I'm sure the XMl will look the same every time.

Ajax - responseText working but responseXML null

I am trying my first AJAX and having a problem with my xml receiving function.
I alert responseText and I can see the xml returned from my server, but when I try and get responseXML I get null and the error.
Here is the php function that builds my xml
header('Content-type: application/xml');
echo("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
echo("<results>");
echo("<table><![CDATA[tablereererere]]></table>");
//echo("<ratedTable>".$_POST['ratedTable']."</ratedTable>\n");
//echo("<table>".$_POST['table']."</table>\n");
//echo("<post_id>".$_POST['post_id']."</post_id>\n");
//echo("<user_id>".$_POST['user_id']."</user_id>\n");
//echo("<rating>".$_POST['rating']."</rating>\n");
echo("</results>");
And here is my javascript function which is processing the returned xml
function ajaxReceiver(http_request) {
//this function continues to run until a result is returned and then it creates the new div
if(http_request.readyState == 4) {
response_xml = http_request.responseXML;
response_text = http_request.responseText;
alert(response_text);
alert(response_xml.getElementsByTagName("table")[0].textContent);
//document.getElementById('floatingNotification').innerHTML = response_text;
// alert(http_request.responseXML.getElementsByTagName("table")[0].textContent);
//ratedTable = responseXML.getElementsByTagName("table").value;
//alert(ratedTable);
//message = response.getElementsByTagName('table')[0].textContent;
//alert(message);
//alert(message);
//this response contains the xml document that was returned by the php function.You can get any values out of the xml document and
//use javascript dom to manipulate the contents on the page
}
}
It may be because, even though you're setting the content-type correctly, you need to have an <xml tag in the top of your response. Also, you aren't closing your last tag properly. This should work:
echo("<?xml version='1.0'?>");
echo("<results>");
echo("<ratedTable>".$_POST['ratedTable']."</ratedTable>");
echo("<table>".$_POST['table']."</table>");
echo("<post_id>".$_POST['post_id']."</post_id>");
echo("<user_id>".$_POST['user_id']."</user_id>");
echo("<rating>".$_POST['rating']."</rating>");
echo("<message>$message</message>");
echo("</results>");
For more info on how to define your XML: http://www.w3.org/TR/REC-xml/#sec-prolog-dtd
You are closing the parent node improperly (</results> not <results/>) and you should (after sanitizing it) wrap all the POSTDATA in <![CDATA[...]]> tags to be safe. Make sure it's UTF8 encoded, too (see utf8_encode())
EDIT: and what wajiw said about the <?xml version="1.0" encoding="UTF-8" ?> tag at the beginning.
Edit: Example CDATA Block Usage
<?xml version="1.0" encoding="UTF-8" ?>
<myNode>
<myData><![CDATA[
Now I just throw in my data, for fun and profit!
This way I can use special, reserved characters like <, > and &!
]]></myData>
</myNode>
Edit Yet Again:
Why not give Content-Type: text/xml, NOT application/xml, a go?
The answer is to put the asynchronous property in the function "open()" to false.
Like this:
ajaxObject.open("POST", "my_XML_Generator.php", false);
ajaxObject.setRequestHeader("Content-type", "text/xml");
ajaxObject.send();
I had the same problem and couldn't solve it until I put my results into subnodes, e.g.
header("Content-Type: text/xml; charset=utf-8");
echo("<?xml version='1.0' encoding='utf-8'?>\n");
echo("<summary>$summary</summary>\n");
echo("<content>$content</content>\n");
didn't work for me for some weird reason, but this does:
header("Content-Type: text/xml; charset=utf-8");
echo("<?xml version='1.0' encoding='utf-8'?>\n");
echo("<page>\n");
echo(" <summary>$summary</summary>\n");
echo(" <content>$content</content>\n");
echo("</page>\n");
My code retrieving the answer is
function retrieveRequest(title)
{
if (_xmlRequest.readyState == 4 && _xmlRequest.status == 200)
{
var xmlResponse = _xmlRequest.responseXML;
_divSummary.innerHTML = xmlResponse.getElementsByTagName("summary")[0].textContent;
_divContent.innerHTML = xmlResponse.getElementsByTagName("content")[0].textContent;
}
}
I had this error happen to our team once and it took me a long time before we realized that the problem was in our XML data returned from the server. In particular, PHP script that generated return XML string was the culprit.
My solution was to remove any white space from the beginning of the PHP script. I mean any spaces, new lines, and/or tabs need to be removed from the beginning of the script, so that the first thing in the script is the <?php tag itself. It turned out that the <?PHP tag was not the first thing on the first line of my PHP script; somehow I started my code on the second line and the first script line was simply an empty one.
It drove me mad and it took some time for me to figure this out, so I hope someone else can benefit from this solution. It is very simple and easy to try if all else fails.

PHP XML IE problem

<?xml version="1.0" ?>
<NBR>
<resultGroups>
<result>Hello</result>
</resultGroups>
</NBR>
i have a n xml created in PHP ike this. i am retruning this XML into javascript and is trying to acces the value of node "result" using
alert($(xmlObj).children('result').text());
In firefox its working fine. but in IE it gives out nothing...
how can i solve this???
It could be you are not sending the correct XML Content-Type header. You should send Content-Type: text/xml with XML content. You should also check that you set the correct charset in both the headers and the file. IE should be able to parse a correct XML response just fine if the JS code is correct and your XML response is valid.
My guess would that is has something to do with the text() function. I am a Prototype guy myself but I ran into a similar problem with IE a little while ago. It came from me trying to pull the textContent value from an element in the DOM. I could grab the value in all other browser but IE was giving me the shaft. After running some tests, this is what I came up with:
IE does not support element.textContent. In most browsers, like FireFox, you would be able to pull the textContent value from element.
Example
<p id="my_element">this is my element</p>
alert($('my_element').textContent); // will alert "this is my element"
In IE, you need to use element.innerHTML. This will return the value you want. Right now, I assume that text() is returning the textContent value and that is why you're getting no dice.
Example
<p id="my_element">this is my element</p>
alert($('my_element').innerHTML); // will alert "this is my element"
Hope this helps!
Are you loading this across SSL?
There is a known issue in IE where sometimes it fails to load XML over SSL:
http://support.microsoft.com/default.aspx?scid=kb;en-us;272359
This page contains more info on how to resolve it:
http://www.blog.lessrain.com/flash-nasty-xml-load-bug-in-internet-explorer/
Ensure that your in your headers that you're specifying the Content-Type and charset, and that your charset (if using utf-8) is utf-8 and not utf8. IE doesn't recognise the latter and doesn't bother to tell you.
So, you want your header to specify the following:
Content-Type: application/xml; charset=utf-8
Have you tried parsing the data out before alert'ing it, and possibly using find instead?
var node_text = $(xmlObj).find('result').text();
alert(node_text);
Otherwise i would suggest trying to change the result tag to something different (like theresult) - everyone knows IE likes to do strange things! :)
If <result> is inside <resultGroups>, then try:
alert($(xmlObj).children('resultGroups').children('result').text());
or, you could try:
alert($($($(xmlObj).children('resultGroups')).children('result')).text());
or even:
alert($($(xmlObj).children('result')).text());
Let me know if any of these work.

Categories