I'm trying to test if the xml file have the tag "<group>"
var xmlhttp = new window.XMLHttpRequest();
xmlhttp.open("GET", "xmlfile.xml", false);
xmlhttp.send(null);
xml = xmlhttp.responseXML.documentElement;
var thegroup = xml.getElementsByTagName('group')[0];
if (!group) {
alert('No <group> in the XML: ' + xml);
return;
} else {
alert(xml + 'have a <group> tag');
}
Even if my xml file have the tag "<group>" the result is always negative, and the variable "thegroup" is undefined.
"xml" give me "[object Element]"
Where is my mistake?
PS: I'm only interested in webkit, I don't care about IE, Opera or Firefox for now.
EDIT : HERE IS MY ACTUAL CODE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=UTF-8">
<title>xmltest</title>
<script type="text/javascript">
function init() {
var xmlhttp = new window.XMLHttpRequest();
xmlhttp.open("GET", "xmlfile.xml");
xmlhttp.send(null);
xmlhttp.onreadystatechange = callbackFunction;
function callbackFunction(){
if (xmlhttp.readyState == 4){
xml = xmlhttp.responseXML.documentElement;
var group = xml.getElementsByTagName('group')[0];
console.debug(xml)
if (!group) {
alert('No <group> in the XML: ' + xml);
return;
} else {
alert(xml + 'have a <group> tag');
}
}
}
};
</script>
</head>
<body onLoad="init();">
</body>
</html>
and my xmlfile.xml :
<?xml version="1.0" ?>
<group type="vertical">
<name>name</name>
<title>title</title>
</group>
At this point the alert is triggered saying :
No <group> in the XML: [object Element]
So maybe my problem is just on the way I try to find the <group> tag ?
XMLHttpRequest is asynchronous, it doesn't work that way. When you use xmlhttp.send(null); you have to define callback function that will be executed when the server responds with the data, otherwise you are trying to access empty data.
The code would look something like this:
var xmlhttp = new window.XMLHttpRequest();
xmlhttp.open("GET", "xmlfile.xml");
xmlhttp.send(null);
xmlhttp.onreadystatechange = callbackFunction;
function callbackFunction(){
if (xmlhttp.readyState == 4){
xml = xmlhttp.responseXML.documentElement;
var thegroup = xml.getElementsByTagName('group')[0];
if (!group) {
alert('No <group> in the XML: ' + xml);
return;
} else {
alert(xml + 'have a <group> tag');
}
}
}
this way, you are using onReadyStateChange to tell the browser to run callbackFunction everytime the server sends back a response. It tests for the readyState to be 4 which means that the request has been completely served.
var thegroup = xml.getElementsByTagName('group')[0];
if (!group) {
alert('No <group> in the XML: ' + xml);
return;
} else {
alert(xml + 'have a <group> tag');
}
What is group? Did you mean thegroup?
Related
I am trying to use XSL to translate an XML file into a neat table. For that I used the examples provided by W3schools which can be located here as a starting point. Yet the browser(chrome) is throwing the error that is described in the title of this post. I even tried copying the exact same example on W3 only to be met with the same error. Tried debugging in Firefox, this is the console output
TypeError: Argument 1 of XSLTProcessor.importStylesheet is not an object.
A similar question was posted before and the solution was in changing the model from synchronous to async. I tried doing that through the onreadystatechange method but without success. Here is the code I worked with.
<html>
<head>
<script>
function loadXMLDoc(filename)
{
if (window.ActiveXObject)
{
xhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
else
{
xhttp = new XMLHttpRequest();
}
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
return xhttp.responseXML;
}
};
xhttp.open("GET", filename);
try {xhttp.responseType = "msxml-document"} catch(err) {} // Helping IE11
xhttp.send("");
}
function displayResult()
{
xsl = loadXMLDoc("cdcatalog.xsl");
xml = loadXMLDoc("cdcatalog.xml");
// code for IE
if (window.ActiveXObject || xhttp.responseType == "msxml-document")
{
ex = xml.transformNode(xsl);
document.getElementById("dataTable").innerHTML = ex;
}
// code for Chrome, Firefox, Opera, etc.
else if (document.implementation && document.implementation.createDocument)
{
xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToFragment(xml, document);
document.getElementById("dataTable").appendChild(resultDocument);
}
}
</script>
</head>
<body onload="displayResult()">
<div id="dataTable" />
</body>
Thank you for all the help!
Here is an example of two asynchronous requests where the callback of one event handler starts the next request whose callback does the transformation. To keep it simple, I have used onload instead of onreadystatechange, if you really need support for old IE versions you will need to adapt the code.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>XMLHttpRequest and onload handler with asynchronous requests</title>
<script>
function load(url, callback) {
var req = new XMLHttpRequest();
req.open('GET', url);
// to allow us doing XSLT in IE
try { req.responseType = "msxml-document" } catch (ex) {}
req.onload = function() {
callback(req.responseXML);
};
req.send();
}
function transform(xml, xsl) {
load(
xml,
function(inputXml) {
load(
xsl,
function(xsltSheet) {
displayResult(inputXml, xsltSheet);
}
);
}
);
}
function displayResult(xmlInput, xsltSheet) {
if (typeof XSLTProcessor !== 'undefined') {
var proc = new XSLTProcessor();
proc.importStylesheet(xsltSheet);
document.getElementById('example').appendChild(proc.transformToFragment(xmlInput, document));
}
else if (typeof xmlInput.transformNode !== 'undefined') {
document.getElementById("example").innerHTML = xmlInput.transformNode(xsltSheet);
}
}
</script>
</head>
<body onload="transform('catalog.xml', 'catalog.xsl')">
<div id="example"></div>
</body>
</html>
Online at http://home.arcor.de/martin.honnen/xslt/test2015072001.html, works fine with current versions of IE, Firefox and Chrome on Windows 8.1.
If you want to start two asynchronous requests directly to load XML and XSLT then you need to do some more work to make sure you know when both documents have been loaded to process them, an example of that is at http://home.arcor.de/martin.honnen/xslt/test2015072101.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>XMLHttpRequest and onload handler with asynchronous requests</title>
<script>
function makeRequest(url, loadedData, property, elementToAddResult) {
var req = new XMLHttpRequest();
req.open('GET', url);
// to allow us doing XSLT in IE
try { req.responseType = "msxml-document" } catch (ex) {}
req.onload = function() {
loadedData[property] = req.responseXML;
if (checkLoaded(loadedData)) {
displayResult(loadedData.xmlInput, loadedData.xsltSheet, elementToAddResult);
};
};
req.send();
}
function checkLoaded(loadedData) {
return loadedData.xmlInput != null && loadedData.xsltSheet != null;
}
function loadAndTransform(xml, xsl, elementToAddResult) {
var loadedData = { xmlInput: null, xsltSheet: null };
makeRequest(xml, loadedData, 'xmlInput', elementToAddResult);
makeRequest(xsl, loadedData, 'xsltSheet', elementToAddResult);
}
function displayResult(xmlInput, xsltSheet, elementToAddResult) {
if (typeof XSLTProcessor !== 'undefined') {
var proc = new XSLTProcessor();
proc.importStylesheet(xsltSheet);
elementToAddResult.appendChild(proc.transformToFragment(xmlInput, document));
}
else if (typeof xmlInput.transformNode !== 'undefined') {
elementToAddResult.innerHTML = xmlInput.transformNode(xsltSheet);
}
}
</script>
</head>
<body onload="loadAndTransform('catalog.xml', 'catalog.xsl', document.getElementById('example'));">
<div id="example"></div>
</body>
</html>
I'm doing my first steps with AJAX and PHP, following a book ("AJAX & PHP: Building Responsive Web Aplicattions"). I tried to do something similar to one of the first exercises on my own. The first time I runned the code it didn't work. I checked it out and I didn't find any mistakes. Then I compared both codes line by line, and they looked exactly the same to me. I couldn't find any difference. The problem is the first code works; the divMessage changes its content at the same time you're writting in the input, but this doesn't happen with my code, and I really can't figure out why, because both codes are practically the same to me.
Original Code (HTML):
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="quickstart.js" language="Javascript"></script>
</head>
<body onload='process()'>
Server wants to know your name:
<input type="text" id="myName"></input>
<div id="divMessage"></div>
</body>
</html>
My code (HTML):
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script language="Javascript" type="text/javascript" src="test.js"></script>
</head>
<body onload='process()'>
Ingress a number:
<input type="text" id="number"></input>
<div id="textbox"></div>
</body>
</html>
=====================
Original Code(JS):=====================
// stores the reference to the XMLHttp object
var xmlHttp = createXMLHttpRequest();
// retrieves the XMLHttpRequest object
function createXMLHttpRequest(){
// will store the reference to the XMLHttp object
var xmlHttp;
// if running IE
if (window.ActiveXObject){
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e) {
xmlHttp = false;
}
}
// if running Mozilla or other browsers
else {
try {
xmlHttp = new XMLHttpRequest();
}
catch(e) {
xmlHttp = false;
}
}
// return the object created or display an error message
if(!xmlHttp){
alert("Error creating the XMLHttpRequest object.");
}
else{
return xmlHttp;
}
}
// make asynchronus HTTP request using XMLHttpRequest object
function process(){
// proceed only if the XMLHttpRequest object isn't busy
if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0){
// retrieves the name typed by the user on the form
// La función encodeURIComponent() reemplaza todos los caracteres
// que no se pueden utilizar de forma directa en las URL por su representación hexadecimal.
name = encodeURIComponent(document.getElementById("myName").value);
// execute the quickstart.php page from the server
xmlHttp.open("GET", "quickstart.php?name=" + name, true);
// define the method to handle server responses
// the function is be called automatically when the state of the request changes
xmlHttp.onreadystatechange = handleServerResponse;
// make the server rqeuest
xmlHttp.send(null);
}
else{
// if the connection is busy, try again after one second
setTimeout('process()', 1000);
}
}
// executed automatically when a message is received from the server
function handleServerResponse(){
// move forward only if the transaction has completed
if (xmlHttp.readyState == 4){
// status of 200 indicates the transaction has completed successfully
if (xmlHttp.status == 200){
// extract the XML retrieved from the server
xmlResponse = xmlHttp.responseXML;
//obtain the document element (the root element) of the XML structure
xmlDocumentElement = xmlResponse.documentElement;
// get the text message, wich is in the first child
// of the document element
helloMessage = xmlDocumentElement.firstChild.data;
// update the client display using the data received from the server
document.getElementById("divMessage").innerHTML = helloMessage;
// restart sequence
setTimeout('process()',1000);
}
// a HTTP status different than 200 signal error
else {
alert ("There was a problem accessing the server: " + xmlHttp.statusText);
}
}
}
My Code (JS):
var xmlHttp = createXMLHttpRequest();
function createXMLHttpRequest(){
var xmlHttp;
if (window.ActiveXObject){
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e){
xmlHttp = false();
}
}
else {
try {
xmlHttp = new XMLHttpRequest();
}
catch(e){
xmlHttp = false;
}
}
if(!xmlHttp){
alert ("El objeto XMLHttpRequest no pudo ser creado.");
}
else {
return xmlHttp;
}
}
function process(){
if (xmlHttp.readyState == 4 || xmlHttp == 0){
number = encodeURIComponent(document.getElementById("number").value);
xmlHttp.open("GET", "test.php?number=" + number, true);
xmlHttp.onreadystatechange = handleServerResponse;
xmlHttp.send(null);
}
else {
setTimeout("process()", 1000);
}
}
function handleServerResponse(){
if (xmlHttp.readyState == 4){
if (xmlHttp.status == 200){
xmlResponse = xmlHttp.responseXML;
xmlDocumentElement = xmlResponse.documentElement;
helloMessage = xmlDocumentElement.firstChild.data;
document.getElementById("textbox").innerHTML = helloMessage;
setTimeout("process()",1000);
}
else {
alert ("Hubo un problema al acceder al servidor: " + xmlHttp.statusText);
}
}
}
=====================
Original Code(PHP):=====================
<?php
// generate the XML output
header('Content-Type: text/xml');
// generate the XML header
echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
// create the <response> element
echo '<response>';
// retrieve the user name
$name = $_GET['name'];
// generate output depending of the user name received from client
$usernames = array('PABLO','JOSE','JUAN','CARLOS','YODA');
if (in_array(strtoupper($name), $usernames))
echo 'Hello ' . htmlentities($name);
else if (trim($name) == '')
echo 'Stranger, please tell me your name.';
else
echo htmlentities($name) . ', I don\'t know you.';
// close the <response> element
echo '</response>';
?>
My Code (PHP):
<?php
header ('Content-type: text/xml');
echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
echo '<response>';
$number = $_GET['number']
echo 'El número ingresado es: ' . htmlentities($number);
echo '</response>';
?>
books.xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<datas>
<book>
<id>
1
</id>
<title>
PHP Enterprise
</title>
<author>
Wiwit
</author>
</book>
<book>
<id>
2
</id>
<title>
PHP Undercover
</title>
<author>
Wiwit
</author>
</book>
</datas>
test.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ajax Client</title>
<script type="text/javascript">
var xmlHttp = createXmlHttpRequestObject();
// creates XMLHttpRequest Instance
function createXmlHttpRequestObject(){
// will store XMLHttpRequest object
// at here
var xmlHttp;
// works all exceprt IE6 and older
try
{
// try to create XMLHttpRequest object
xmlHttp = new XMLHttpRequest();
}
catch(e)
{
// assume IE 6 or older
try
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e){ }
}
// return object or display error
if (!xmlHttp)
alert("Error creating the XMLHttpRequest Object");
else
return xmlHttp;
}
function process()
{
if(xmlHttp)
{
try
{
xmlHttp.open("Get","books.xml", true);
xmlHttp.onreadystatechange = handleRequestStateChange;
xmlHttp.send(null);
}
catch(e)
{
alert("Can't connect to server\n" + e.toString());
}
}
}
function handleRequestStateChange()
{
myDiv = document.getElementById("myDivElement");
if(xmlHttp.readyState == 1)
{
myDiv.innerHTML += "Request status: 1 (loading) <br/>";
}
else if (xmlHttp.readyState == 2)
{
myDiv.innerHTML += "Request status: 2 (loaded) <br/>";
}
else if (xmlHttp.readyState == 3)
{
myDiv.innerHTML += "Request status: 3 (interactive) <br/>";
}
else if (xmlHttp.readyState == 4)
{
if(xmlHttp.status == 200)
{
try
{
handleXMLData();
}
catch(e)
{
alert("Error reading the response: " + e.toString());
}
}
else
{
alert("Problem retrieving data:\n" + xmlHttp.statusText);
}
}
}
function handleXMLData()
{
var xmlResponse = xmlHttp.responseXML;
xmlRoot = xmlResponse.documentElement;
idArray = xmlRoot.getElementsByTagName("id");
titleArray = xmlRoot.getElementsByTagName("title");
authorArray = xmlRoot.getElementsByTagName("author");
var html = "";
for( var i=0; i<titleArray.length; i++)
{
html += idArray.item(i).firstChild.data + ", " + titleArray.item(i).firstChild.data + ", " + authorArray.item(i).firstChild.data + "<br/>";
}
myDiv = document.getElementById("myDivElement");
myDiv.innerHTML += "Server says: <br/>" + html;
}
console.log(xmlRoot);
</script>
</head>
<body onload="process()">
Our collections:
<div id="myDivElement" />
</body>
</html>
Above code is taken from: http://www.phpeveryday.com/articles/AJAX-Client-Side-Processing-XML-Data-use-XMLHttpRequest-P356.html
In this function function handleXMLData(), some places use var such as var xmlResponse = xmlHttp.responseXML;, some places did not use var, such as: xmlRoot = xmlResponse.documentElement; so my question is:
why not put var in front of xmlRoot?
usually inside function(){}, if we do not put var in front of variable, it will be global variable, such as:
function test()
{ gar = '9';}
test();
console.log(gar);
But when I put console.log(xmlRoot); just before tag </script>, in chrome console, it shows:Uncaught ReferenceError: xmlRoot is not defined, why? Is not xmlRoot a global variable since there is no var in front of it?
var may not have used here because the author wants the variable to be a global one
It is throwing the error because when console.log(xmlRoot);, the execution context is unaware about xmlRoot since handleXMLData may not have executed yet (because it a used in the callback function to an asynchronous call)
xmlRoot will be a global variable if it has been defined. If the function that refers to it has not been called, xmlRoot won't be defined.
You tested xmlRoot just before the script exits, i.e. during the first execution of the code, before handleXMLData() had been called.
Hi all I have to connect to an external server to retrieve data.
They told me to use their script and I have to modify something because it was wrong. Now I ahve a problem when I try to lunch my request.
Return me an error into my internet explorer console
SCRIPT10: The data required for the completion of this operation are
not yet available.
This is my javascript page, the problem I think is because the query doesn't finish in time to print my result. How can I print the result when they are ready and don't return me error?
I have try to comment all my request and leave only the method "open" but the error return me every time. Why??
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript">
var req = null ;
function sendRequest(){
var urlStr="www.test.it";
var xmlString="";
xmlString+="<?xml version='1.0' encoding='UTF-8'?><some xml>";
createHTTPRequestObject();
var resp = getResponseText(urlStr+"?"+xmlString,null);
var xmlDoc;
xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
xmlDoc.async = false;
xmlDoc.loadXML(resp);
alert(xmlDoc.xml);
}
function createHTTPRequestObject(){
req=null ;
var pXmlreq = false ;
if (window.XMLHttpRequest) {
pXmlreq = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
try{
pXmlreq = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e1) {
try{
pXmlreq = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e2) {
}
}
}
req = pXmlreq ;
}
function getResponseText(action,query,method,async,contenttype){
if(method==null){
method="POST";
}
if(async==null){
async="true";
}
if(contenttype==null){
contenttype = "application/x-www-form-urlencoded";
}
req.open(method,action, async);
req.setRequestHeader("Content-Type", contenttype);
if(query){
req.send(query);
}else{
req.send();
}
return req.responseText ;
}
</script>
</head>
<body>
<input type="button" name="Request" value="Request" onclick="sendRequest();"/>
<div id="content" />
</body>
</html>
You are trying to read the responseText before it is ready. Looks like you are treating a asynchronous call as synchronous. That would be the issue.
I'm trying to show an AJAX loader gif while an asynchronous POST request is performed. Unfortunatelly this works not in Interet Explorer! The Gif is shown, but the request process seems to stop respectivly the changed webcontent will not be shown. On FF, Opera, Safari everything is fine! Any ideas?
http_request.onreadystatechange = function()
{
if (http_request.readyState < 4)
{
var waitingPageBody = '< img src="/img/ajaxloader.gif" alt="request in progress..."/>';
document.body.innerHTML = waitingPageBody;
}
else //if (http_request.readyState == 4)
{
if (http_request.status == 200)
{
document.body.innerHTML = http_request.responseText;
}//end of if (http_request.status == 200)
else
{//other http statuses
alert("There was a problem");
}
} //end of else if http_request.readyState == 4
}
...
The window will freeze, because the request is synchronous. The browser freezes whenever a javascript code is executing and running a synchronous request is equivalent to running javascript code the whole time the browser is waiting for a response.
You've shown us the event handling code but are you calling open() and send()?
Your event handling code seems to work in FF3.5, IE6 and IE8:
http://jsbin.com/ocoka (Editable via: http://jsbin.com/ocoka/edit)
Full source:
<!DOCTYPE html>
<html>
<head>
<title>Sandbox</title>
<script>
function load() {
var http_request = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
http_request.open('GET', 'http://jsbin.com/blank.html', true);
http_request.onreadystatechange = function() {
if (http_request.readyState < 4) {
var waitingPageBody = 'request in progress...';
document.body.innerHTML = waitingPageBody;
}
else {
//if (http_request.readyState == 4)
if (http_request.status == 200) {
document.body.innerHTML = '<pre>' + entity(http_request.responseText) + '</pre>';
}//end of if (http_request.status == 200)
else {
//other http statuses
alert("There was a problem");
}
} //end of else if http_request.readyState == 4
};
http_request.send();
}
function entity(str) {
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
};
</script>
</head>
<body onload="load();">
</body>
</html>
EDIT:
According to your comments, you are making an synchronous request. In that case you don't have to (shouldn't?) use the event handler at all, just run your code before and after the call to send():
Hosted Demo (tested in FF3.5, IE6 and IE8):
http://jsbin.com/elehu (Editable via: http://jsbin.com/elehu/edit)
Full source:
<!DOCTYPE html>
<html>
<head>
<title>Sandbox</title>
<script>
function load() {
var http_request = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
http_request.open('GET', 'http://jsbin.com/blank.html', false);
var waitingPageBody = 'request in progress...';
document.body.innerHTML = waitingPageBody;
/***
setTimeout with 0ms delay makes sure that the
'request in progress...' message is displayed
before the browser thread is blocked by the send() method.
***/
setTimeout(function(){
http_request.send();
if (http_request.status == 200) {
document.body.innerHTML = '<pre>' + entity(http_request.responseText) + '</pre>';
}//end of if (http_request.status == 200)
else {
//other http statuses
alert("There was a problem");
}
}, 0);
}
function entity(str) {
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
}
</script>
</head>
<body onload="load();">
</body>
</html>