|
"AJAX" - That's right, I said it! (XML DOM) ***Please Help*** |
bamccaig
Member #7,536
July 2006
|
(Some names have been changed to protect the innocent... ;D) Today at work I was asked to create a javascript "class" to manage some basic AJAX requests. By the end of the day I have one working synchronously, but not asynchronously. My search of the forums revealed suggestions for using JSON (it looks worse than the XML tree) and parsing of XMLHttpRequest.responseText. However, I've been asked to use XML and my class is already designed to parse the XML prettily so those aren't options (and I think I'd prefer to get the XML working anyway). If you wish to skip the code below and just answer my question I'm trying to create an XMLDOM object from the XMLHttpRequest.responseXML property. As is, the class is designed similar to a recordset to make it feel like you were simply accessing a database table. For example:
The only methods required to implement the class in this example are Request(), RecordCount(), EOF(), and Item(). When the form loads the above code would draw something like the following: RecordCount: 3 +------------+------------+------------+ | FieldName1 | FieldName2 | FieldName3 | +------------+------------+------------+ | 1 | foo | 2352 | +------------+------------+------------+ | 2 | bar | 34243 | +------------+------------+------------+ | 3 | foo2 | 12 | +------------+------------+------------+ Using the following XML: <?xml version="1.0" encoding="iso-8859-1"?> <Request> <Sample> <Records> Anybody still reading, thank you. That Request() method of the MyAJAXClass class is currently loading an XML file into an XMLDOM object. As far as I can tell, there is no way to set a callback function for when it finishes loading (asynchronously) so I enforce a synchronous load. The plan, however, is to asynchronously load the xml file and process it when it finishes. Does anybody know how to define an onLoad callback for the XMLDOM object or preferably how to create an XMLDOM object from the XMLHttpRequest.responseXML? (Some names have been changed to protect the innocent... ;D) -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
kazzmir
Member #1,786
December 2001
|
I'm mildly impressed you couldn't figure it out by yourself but all you need to do for asynchronous processing is ajax_thing.onreadystatechange = function{ ... } Here some code I used:
|
Matthew Leverton
Supreme Loser
January 1999
|
Let me just say that using XML is crazy dumb. Whoever told you to do that better have an incredibly good reason for doing so. If not, disobey and use JSON. And regarding kazzmir's code, I've found it's best to check for the ActiveX control first. IE 7's native control is apparently buggy and broken. |
Jonatan Hedborg
Member #4,886
July 2004
|
Haven't you heard? XML is like a faucet. A faucet that when opened spews out endless amounts of money. It also gets you laid. A lot.
|
bamccaig
Member #7,536
July 2006
|
kazzmir said: I'm mildly impressed you couldn't figure it out by yourself but all you need to do for asynchronous processing is ajax_thing.onreadystatechange = function{ ... } I'm mildly impressed myself. The problem isn't with using asynchronous processing. The problem is creating an XML DOM (XMLDOM object) from the XMLHttpRequest object's responseXML property. Alternatively, if you know how to use the XMLDOM object to load() an XML file asynchronously (as far as I can tell there is no onreadystatechange event for XMLDOM) as you do for XMLHttpRequest that would probably solve my problem as well. Matthew Leverton said: Let me just say that using XML is crazy dumb. Whoever told you to do that better have an incredibly good reason for doing so. If not, disobey and use JSON. I'm not really a huge fan of XML, but JSON looks pretty ugly to me. Disobeying isn't really an option if I want to keep my job, though I could recommend a change. I don't really see the point. I appreciate the advice, but what I really want/need is to know how to create the XMLDOM object from the XMLHttpRequest, since the processing of XML is already taken care of. As I mentioned, implementing my class the only method calls I need to access data are the constructor to create the object, Request() to make the request, and from there EOF() and Item() to access the fields. Matthew Leverton said: And regarding kazzmir's code, I've found it's best to check for the ActiveX control first. IE 7's native control is apparently buggy and broken. Noted. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
ImLeftFooted
Member #3,935
October 2003
|
XML is the way to go. Much better then JSON. Answering specific questions first... Quote: Does anybody know how to define an onLoad callback Don't. Its ugly, its hacky, encourages globals and there is no good reason for it. If you would like to background the function that is calling xmlHttpRequest::send so it executes in its own thread, that makes sense. You can use SetTimeout with a timeout of 0 to achieve this. Quote: how to create an XMLDOM object from the XMLHttpRequest.responseXML It already is. Quote: When the form loads the above code would draw something like the following: RecordCount: 3 +------------+------------+------------+ Using the following XML: <?xml version="1.0" encoding="iso-8859-1"?> Ok lets look at how you might do this... Heres how to parse the xml itself: You could also use xpath which could theoritcally cleaner, but makes you less backwards-compatible. As for how to display that table (construct the HTML with values etc), I have the (I believe) perfect method. Unfortunetly I'm not in the mood to explain it right now, so maybe later. |
Matthew Leverton
Supreme Loser
January 1999
|
Quote: XML is the way to go. Much better then JSON. Answering specific questions first... Uhm, no. XML is only better if you need to use XPath to access large amounts of arbitrary data. And even then, browsers' (IE) native XPath support is not good. If you are dealing with known data (either small datasets or for iteration), JSON is way better. eval(json); alert(json.foo); The only other reason to use XML is if you actually already have well-formed XML documents stored on the server. |
ImLeftFooted
Member #3,935
October 2003
|
Ah, so thats how json works.. cool. |
bamccaig
Member #7,536
July 2006
|
Dustin Dettmer said: var records = xml.getElementsByTagName("Record"); That sounds right and I hope it is, but I'm having trouble utilizing it right now. Can you see what might be the problem with this:
It's very possible there is a bug (or many) in my code somewhere, but this is basically blowing up. Firebug detects an uncaught exception (which is messy) and IE7's <select> appears to somewhat "break". Firebug said: uncaught exception: [Exception... "Component returned failure code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIXMLHttpRequest.open]" nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)" location: "JS frame :: javascript: eval(__firebugTemp__); :: anonymous :: line 1" data: no] Line 0 The exception caught by firebug isn't necessarily from the block of code that I showed you... And I'm not working with the code I wrote at work today; I'm using old code I hacked together experimenting with AJAX an unknown number of months ago... ** EDIT ** Dustin Dettmer said: Ah, so thats how json works.. cool. Actually, after looking up JSON syntax on Wikipedia it actually looks much nicer than the other threads made it seem. I didn't know you could represent objects with JSON... And for the record, it looks a lot nicer when carried over multiple lines. I still want help parsing the XML from XMLHttpRequest.responseXML, however, I'll also play with JSON and consider recommending it to the company.
-- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
ImLeftFooted
Member #3,935
October 2003
|
The error you pasted I believe I've seen before. I think its caused by problems using the XmlHttpRequest object. Maybe its time to rewrite that 'experimental AJAX from an unknown number of months ago'. Quote: Can you see what might be the problem with this: Uh well that depends on what you're doing. Technically speaking that could be 100% legitmate javascript. I have a hard time reading it because of all your redundant calls to getElementsByTagName. You should really be caching the results, and then maybe even displaying error messages when your indecies are invalid instead of assuming the tags are all there. All that aside, I discovered the perfect way to insert data into a webpage about 2 days ago (couldn't fall asleep cause I was figuring it out). If I'm more in the mood later I'll explain it. edit I deal with that enough at work. |
bamccaig
Member #7,536
July 2006
|
Dustin Dettmer said: On second thought I don't think I'm going to explain it. Please do... -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
kazzmir
Member #1,786
December 2001
|
earlier ddustin said: I have the (I believe) perfect method. Unfortunetly I'm not in the mood to explain it right now, so maybe later.
then he said: All that aside, I discovered the perfect way to insert data into a webpage about 2 days ago (couldn't fall asleep cause I was figuring it out). If I'm more in the mood later I'll explain it. edit Arrogance: its whats for dinner. |
ImLeftFooted
Member #3,935
October 2003
|
Its slowly developed over the years. I stopped caring to stop it. |
Matthew Leverton
Supreme Loser
January 1999
|
You may also want to check out http://json.org/, as it has libraries for various languages to convert the native objects to a JSON string. |
bamccaig
Member #7,536
July 2006
|
Matthew Leverton said: You may also want to check out http://json.org/, as it has libraries for various languages to convert the native objects to a JSON string. Much appreciated. There's an ASP/VBScript class which might make it a little bit easier to work with. My only fear is licensing issues and whether or not my company would want to use it, though the "license" does say to use it freely so long as the credits are maintained. ** EDIT ** I'm trying to parse the XML and I'm getting an error that gobjXMLDOM.getElementsByTagName("SampleElement")[0] doesn't support the getElementsByTagName method. What am I doing wrong? I checked with IE's script debugger and there is an object returned by gobjXMLDOM.getElementsByTagName("SampleElement")[0], but it doesn't seem to be the first "SampleElement" element, rather, it seems to be the <?xml version="1.0" encoding="iso-8859-1"?> element...
** EDIT (10 minutes after the first) ** However, when I tried gobjXMLDOM.documentElement.getElementsByTagName("SampleElement")[0] it seemed to work. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Samuel Henderson
Member #3,757
August 2003
|
err. I was asked to bump this thread, sooo... bump? Edit: Oh snap. That's the last time I bump for anyone. ================================================= |
bamccaig
Member #7,536
July 2006
|
Samuel Henderson said: err. I was asked to bump this thread, sooo... bump? Yes, and as fate would have it within minutes of the bump I figured out the problem... Thanks though. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
|