Using the responseXML Property

In your first Netbeans AJAX application, you made use of the responseText property of the XMLHTTPRequest object. Although that is certainly the easiest way to get data from the server, it really only works if the data is pre-formatted on the server. If the data is not pre-formatted, often you are charged with parsing the text returned. That can get pretty messy in a hurry. In most cases, you will use XML as the transport mechanism for your applications. In fact, one of the strengths of XML is that it is easily parsed using the DOM. The good news is that the responseXML property returns a DOM document.

1. Start Netbeans and open your AjaxStart web application. If you haven't created the application, see the lesson detailing your first Netbeans AJAX web application.

2. Right-click the Web Pages folder and choose New > HTML...

3. In the resulting dialog, name the file xmlRequest and click Finish.

4. Netbeans will create the file and open it in the editor. Add the following code between the <body> tags:

<form>

<input type="button" onclick="getData()" value="Get Message"/>

<div id="message">Message Goes Here</div>

</form>

5. Open a script block and add the following code:

<script type="text/javascript"> var req=null; function xhr(){ try { // Firefox, Opera 8.0+, Safari req=new XMLHttpRequest(); } catch (e) { // Internet Explorer try { req=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { req=new ActiveXObject("Microsoft.XMLHTTP"); } } return req; } function getData(){
req = new xhr();
req.open("get","simpleRequestData.xml");
req.onreadystatechange = showIt;
req.send(null);

}

 		function showIt(){
   		if(req.readyState==4){
   			if(req.status==200){
   				var doc = req.responseXML;
   				var msgNodes = doc.documentElement.getElementsByTagName('message');
   				var msg = msgNodes[0].firstChild.nodeValue;
   				document.getElementById("message").innerHTML = msg;
   			}
   		}
   	}                
</script>

You've seen most of this code before. The new parts exist in the showIt() function. First, a variable is created to hold the responseXML sent back from the server. Remember, this is a DOM document so you can traverse the node tree just as any other DOM document. Then, the msgNodes variable holds the nodeList returned from the getElementsByTagName() method called on the document. The nodeList is a collection that acts very much like an array of nodes. You can traverse the nodes in the collection by their index. Next a handle to the message <div> in the HTML document is created. Then, a <message> element is created and populated with the content returned from the request. Finally, the text inside the original message is cleared and the message node is appended to the message <div> in the HTML document.

6. Right-click the xmlRequest.html file and choose Run File. Netbeans will start Tomcat and serve the file to your browser. Click the button and you should see the message change.

Aside from the code, how do you know anything happened? Good question. That brings up some interesting things about AJAX that change the way things work on the web. For example, if you were to view the source of the page, you would see the original source code - not the changed code! Let's see if we can prove that the message returned is an actual node instead of text.

7. Add a <style> block to the head of the document:

    <style>
        #message{color:red;}
        message{display:block;color:green;}
    </style>

The first style rule gets applied to the HTML <div> tag. The second rule gets applied to any elements of type <message>. Save the file and reload it in the browser. The original text should now be red. When you click on the button, the message should become green. You can't do that with text!

8. External Requests. One of the rules the XMLHTTPRequest adheres to is that it will not open or send requests to outside domains. That is, you can only make requests of resources on the same server. To prove that, let's see if we can load an XML news feed from moreover.com. Moreover.com exposes newsfeeds in a variety of formats for hundreds of topics. It would be great to be able to update a news feed asynchonously via AJAX. Unfortunately, without doing so on the server side, that's not possible. Modify your getData() function to the following:

     function getData(){
            req = new xhr();
            req.open("get","http://p.moreover.com/cgi-local/page?c=Java%20news&o=xml");
            req.send(null);
            if(req.readyState==4){
                if(req.status==200){
                    var doc = req.responseXML;
                    var nodes = doc.documentElement.firstChild.childNodes;
                    document.getElementById('message').appendChild(msgNodes[0]);
                    document.getElementById('btn').value = 'Update Feed';
                }
            }
        }

Save the file and reload it in your browser. If you are using Firefox, choose Error Console from the Tools menu to display the error message. Click the button.

As you can see, external calls are denied. You can paste the link in the script directly into your browser to see what the XML feed actually looks like.