I have 2 xml documents stored which I get from an AJAX post request and I would like to check if they are the same. Obviously xml1 == xml2 is not working. Is there another way that I could make this work?
Try this. It parses the XML document using the method in this question and compares the two using isEqualNode.
function parseXMLString(xmlString) {
var xmlDoc;
if (window.DOMParser) {
var parser = new DOMParser();
xmlDoc = parser.parseFromString(xmlString, "text/xml");
} else // Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(xmlString);
}
return xmlDoc;
}
var xmlObj1 = parseXMLString('<hello>world</hello>');
var xmlObj2 = parseXMLString('<hello>world</hello>');
var xmlObj3 = parseXMLString('<hello>world2</hello>');
var xmlObj4 = parseXMLString('<hello2>world</hello2>');
console.log(xmlObj1.isEqualNode(xmlObj2));
console.log(xmlObj1.isEqualNode(xmlObj3));
console.log(xmlObj1.isEqualNode(xmlObj4));
If you're using jQuery, you can parse the XML document using parseXML().
I'm having a lot of difficulty with this project.
My aim is to write the results of a HTML form to an XML Document using Javascript.I have absolutely no idea how to do it.
Reason why I'm coming here is that I want to be sure that I'm on the right track. So far, I'm writing only one line "\n" just to test things out.
Here is my current JavaScript
var xhr = false;
if (window.XMLHttpRequest)
{
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
function StoreRegXml()
{
xhr.open("GET", "php.php?" + Number(new Date), true);
xhr.onreadystatechange = getData;
xhr.send(null);
}
function getData()
{
if ((xhr.readyState == 4) && (xhr.status == 200))
{
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
var fso = new ActiveXObject("Scripting.FileSystemObject");
var filename = "customer.xml";
var file = fso.CreateTextFile(filename, true);
file.WriteLine('<?xml version="1.0" encoding="utf-8"?>\n');
file.Close();
}
}
Am I on the right track?
Edit: I'm adding alerts('test1'); to see where the code is going wrong and it stops at
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
Any ideas?
Inside the browser to create and populate an XML DOM document you can use the W3C DOM APIs with e.g.
var xmlDoc = document.implementation.createDocument(null, 'root', null);
var foo = xmlDoc.createElement('foo');
foo.textContent = 'bar';
xmlDoc.documentElement.appendChild(foo);
console.log(xmlDoc);
This creates an in memory XML DOM document, not an XML file. You can then for instance send the xmlDoc with XMLHttpRequest to the server.
I have created this website
http://www.tylertracy.com/testing/Xml/App%20veiwer%205-28.php
It works fine on most browsers and on iPhone simulators, but it doesn't work on a real iPhone. I have narrowed it down to the XMLHttpRequest(). It seems that when I am getting the xml, I can not read the children of [object Element] it returns undefined. This is very baffling i do not understand.
Here is my code for getting the XML
function convertXml (path) {
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest(); // code for IE7+, Firefox, Chrome, Opera, Safari
}else{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); // code for IE6, IE5
}
xmlhttp.open("GET",path,false);
xmlhttp.send();
xml=xmlhttp.responseXML.getElementsByTagName("app");
var foo = [];
for (var i = 0; i <= xml.length-1; i++) {
foo[i] = {};
for (var j = 0; j <=xml[i].children.length-1; j++) { // get all children of the app and make it a part in the object
foo[i][xml[i].children[j].tagName] = xml[i].children[j].innerHTML.trim();//super complicated
}
}
return foo;
}
After much experimenting i have discovered that on iPhone the request returns a [object Document] while the computer returns a [object XMLDocument]. I don't know what this means, but i feel like it is where my problem is coming from. is there a way of maybe converting between these?
I have since then updated the code to jQuery seeing if the issue still persists, which it does.
Here is the new jQuery
function getXML (path) {
//gets text version of the xml doc
var response = $.ajax({ type: "GET",
url: "testingXml.xml",
async: false,
}).responseText;
//converts text into xmlDoc
parser=new DOMParser();
xmlDoc=parser.parseFromString(response,"text/xml");
return xmlDoc;
}
function xmlToObject (x) {
var xml = x.getElementsByTagName("app"); //get all the xml from the root
var foo = [];
for (var i = 0; i <= xml.length-1; i++) {
foo[i] = {}; // make the object
for (var j = 0; j <=xml[i].children.length-1; j++) { //get all of the children of the main tag
foo[i][xml[i].children[j].tagName] = xml[i].children[j].innerHTML.trim(); //super complicated
}
}
return foo;
}
Then to get the array, you would write this code xmlToObject(getXML("testingXml.xml"))
The issue is still happening, on computer it is fine, but on iPhone (Google, Safari, Firefox, Oprah) It seems that the xml just isn't displaying.
I'm getting
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/
in the Google Chrome console when opening your page. This could be why it won't load on iOS: instead of just logging a warning, Apple decided to ignore such requests on mobile devices to prevent the browser from freezing.
Try with
xmlhttp.open("GET",path,true);
and a xhr.onload handler as described in MDN's "Synchronous and asynchronous requests".
Im porting a browser extension from FF to chrome. I have this XMLHttpRequest, which works fine:
var xhrdata = new XMLHttpRequest(),
xhrdata.onreadystatechange = function () {
if (xhrdata.readyState === 4) {
if (xhrdata.status === 200) {
getJXONTree(xhrdata.responseXML);
}
}
};
xhrdata.open("GET", "mydomain.com/my.xml", true);
xhrdata.responseType = "document";
xhrdata.send();
This send the .responseXML over to this function (shortened)
function getJXONTree(oXMLParent) {
var vResult = true, nLength = 0, sCollectedTxt = '';
if (oXMLParent.hasAttributes()) {
vResult = {};
[...]
This works absolutely fine in firefox, but in chrome, polling the exact same XML with the exact same code, I get this error:
TypeError: Object #<Document> has no method 'hasAttributes'
What am I missing here?
Firefox is more lenient when it comes to this, but it has to be:
xhr.responseXML.documentElement
since documents dont have any attributes. thanks #robW
I've been having some weird issues when it comes to make an AJAX request and handling the response.
I am making an ajax call for an xml file. however when i get the response the xhr.responseText property works fine in firefox but not in IE.
Another thing is that I am trying to access the xhr.responseXML as XMLDocument, but it tells me in firefox it tells me that xhr.responseXML is undefined in ie it doesnt even show me the undefined error or displays the output.
This is the code I am using to make the request:
var ajaxReq = function(url, callback) {
//initialize the xhr object and settings
var xhr = window.ActiveXObject ?
new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(),
//set the successful connection function
httpSuccess = function(xhr) {
try {
// IE error sometimes returns 1223 when it should be 204
// so treat it as success, see XMLHTTPRequest #1450
// this code is taken from the jQuery library with some modification.
return !xhr.status && xhr.status == 0 ||
(xhr.status >= 200 && xhr.status < 300) ||
xhr.status == 304 || xhr.status == 1223;
} catch (e) { }
return false;
};
//making sure the request is created
if (!xhr) {
return 404; // Not Found
}
//setting the function that is going to be called after the request is made
xhr.onreadystatechange = function() {
if (!httpSuccess(xhr)) {
return 503; //Service Unavailable
}
if (xhr.responseXML != null && xhr.responseText != null &&
xhr.responseXML != undefined && xhr.responseText != undefined) {
callback(xhr);
}
};
//open request call
xhr.open('GET', url, true);
//setup the headers
try {
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Accept", "text/xml, application/xml, text/plain");
} catch ( ex ) {
window.alert('error' + ex.toString());
}
//send the request
try {
xhr.send('');
} catch (e) {
return 400; //bad request
}
return xhr;
};
and this is how i am calling the function to test for results:
window.onload = function() {
ajaxReq('ConferenceRoomSchedules.xml', function(xhr) {
//in firefox this line works fine,
//but in ie it doesnt not even showing an error
window.document.getElementById('schedule').innerHTML = xhr.responseText;
//firefox says ''xhr.responseXML is undefined'.
//and ie doesn't even show error or even alerts it.
window.alert(xhr.reponseXML.documentElement.nodeName);
});
}
This is also my first attempt to work with AJAX so there might be something that I am not looking at right.
I've been searching crazy for any indications of why or how to fix it, but no luck there.
any ideas would be great.
EDIT:
I know this would be better with a framework, but the boss doesn't want to add a framework for just an ajax functionality ('just' is not a fair word for ajax :P). So I am doing it with pure javascript.
The XML file is well-formed, I see it well in the web browser, but for completion this is the testing file I am using:
<?xml version="1.0" encoding="utf-8"?>
<rooms>
<room id="Blue_Room">
<administrator>somebody#department</administrator>
<schedule>
<event>
<requester>
<name>Johnny Bravo</name>
<email>jbravo#department</email>
</requester>
<date>2009/09/03</date>
<start_time>11:00:00 GMT-0600</start_time>
<end_time>12:00:00 GMT-0600</end_time>
</event>
</schedule>
</room>
<room id="Red_Room">
<administrator>somebody#department</administrator>
<schedule>
</schedule>
</room>
<room id="Yellow_Room">
<administrator>somebody#department</administrator>
<schedule>
</schedule>
</room>
</rooms>
EDIT 2:
Well the good news is that I convinced my boss to use jQuery, the bad news is that AJAX still perplexes me. I'll read more about it just for curiousity. Thanks for the tips and I gave the answer credit to Heat Miser because he was the closest working tip.
I was having the same problem a few years ago, then I gave up on responseXML and began always using responseText. This parsing function has always worked for me:
function parseXml(xmlText){
try{
var text = xmlText;
//text = replaceAll(text,"<","<");
//text = replaceAll(text,">",">");
//text = replaceAll(text,""","\"");
//alert(text);
//var myWin = window.open('','win','resize=yes,scrollbars=yes');
//myWin.document.getElementsByTagName('body')[0].innerHTML = text;
if (typeof DOMParser != "undefined") {
// Mozilla, Firefox, and related browsers
var parser=new DOMParser();
var doc=parser.parseFromString(text,"text/xml");
//alert(text);
return doc;
}else if (typeof ActiveXObject != "undefined") {
// Internet Explorer.
var doc = new ActiveXObject("Microsoft.XMLDOM"); // Create an empty document
doc.loadXML(text); // Parse text into it
return doc; // Return it
}else{
// As a last resort, try loading the document from a data: URL
// This is supposed to work in Safari. Thanks to Manos Batsis and
// his Sarissa library (sarissa.sourceforge.net) for this technique.
var url = "data:text/xml;charset=utf-8," + encodeURIComponent(text);
var request = new XMLHttpRequest();
request.open("GET", url, false);
request.send(null);
return request.responseXML;
}
}catch(err){
alert("There was a problem parsing the xml:\n" + err.message);
}
}
With this XMLHttpRequest Object:
// The XMLHttpRequest class object
debug = false;
function Request (url,oFunction,type) {
this.funct = "";
// this.req = "";
this.url = url;
this.oFunction = oFunction;
this.type = type;
this.doXmlhttp = doXmlhttp;
this.loadXMLDoc = loadXMLDoc;
}
function doXmlhttp() {
//var funct = "";
if (this.type == 'text') {
this.funct = this.oFunction + '(req.responseText)';
} else {
this.funct = this.oFunction + '(req.responseXML)';
}
this.loadXMLDoc();
return false;
}
function loadXMLDoc() {
//alert(url);
var functionA = this.funct;
var req;
req = false;
function processReqChange() {
// alert('reqChange is being called');
// only if req shows "loaded"
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200) {
// ...processing statements go here...
eval(functionA);
if(debug){
var debugWin = window.open('','aWindow','width=600,height=600,scrollbars=yes');
debugWin.document.body.innerHTML = req.responseText;
}
} else {
alert("There was a problem retrieving the data:\n" +
req.statusText + '\nstatus: ' + req.status);
if(debug){
var debugWin = window.open('','aWindow','width=600,height=600,scrollbars=yes');
debugWin.document.body.innerHTML = req.responseText;
}
}
}
}
// branch for native XMLHttpRequest object
if(window.XMLHttpRequest) {
try {
req = new XMLHttpRequest();
} catch(e) {
req = false;
}
// branch for IE/Windows ActiveX version
} else if(window.ActiveXObject) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
req = false;
}
}
}
if(req) {
req.onreadystatechange = processReqChange;
if(this.url.length > 2000){
var urlSpl = this.url.split('?');
req.open("POST",urlSpl[0],true);
req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
req.send(urlSpl[1]);
} else {
req.open("GET", this.url, true);
req.send("");
}
}
}
function browserSniffer(){
if(navigator.userAgent.toLowerCase().indexOf("msie") != -1){
if(navigator.userAgent.toLowerCase().indexOf("6")){
return 8;
}else{
return 1;
}
}
if(navigator.userAgent.toLowerCase().indexOf("firefox") != -1){
return 2;
}
if(navigator.userAgent.toLowerCase().indexOf("opera") != -1){
return 3;
}
if(navigator.userAgent.toLowerCase().indexOf("safari") != -1){
return 4;
}
return 5;
}
Granted, this is very old code, but it is still working for me on a site I built a few years ago. I agree with everyone else though I typically use a framework nowadays so I don't have to use this code or anything like it anymore.
You can ignore some of the particulars with the split, etc... in the Request onreadystate function. It was supposed to convert the request to a post if it was longer than a certain length, but I just decided it was always better to do a post.
This problem occurs mostly when content type is mis-detected by the browser or it's not sent correctly.
Its easier to just override it:
var request = new XMLHttpRequest();
request.open("GET", url, false);
request.overrideMimeType("text/xml");
request.send(null);
return request.responseXML;
Not sure why... This problem occurs only with Safari and Chrome (WebKit browsers, the server sends the headers correctly).
Are you calling the URL relative to the current document? Since IE would be using the ActiveXObject, it might need an absolute path, for example:
http://some.url/ConferenceRoomSchedules.xml
As for the XML, are you sure it's well-formed? Does it load in an XML editor, for instance?
What I can suggest you is to take a look at frameworks that hide and manage these cross-browser issues for you (in a reliable way). A good point here is jQuery. Doing these things yourself can become quite difficult and complex.
This may be what you need.
//Edit:
This is how the w3school shows it:
function ajaxFunction()
{
var xmlhttp;
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
else
{
alert("Your browser does not support XMLHTTP!");
}
}
To avoid your cross browser problems (and save yourself coding a lot of items that a strong community has already developed, tested, and reviewed), you should select a javascript library. JQuery and Dojo are great choices.
I believe that your web server need to serve correct response headers with 'ConferenceRoomSchedules.xml' e.g. Content-Type: text/xml or any other xml type.
The answer provided by Aron in https://stackoverflow.com/a/2081466/657416 is from my point of view the simplest (and the best) one. Here is my working code:
ajax = ajaxRequest();
ajax.overrideMimeType("text/xml");
ajax.open("GET", myurl;