You can validate your XML data after it’s been downloaded if you use a browser like Internet Explorer. For example, say that you add a document type definition (DTD) to event.xml, creating eventdtd.xml:
<?xml version="1.0"?> <!DOCTYPE events [ <!ELEMENT events (event*)> <!ELEMENT event (event_title, event_number, subject, date, people*)> <!ELEMENT event_title (#PCDATA)> <!ELEMENT event_number (#PCDATA)> <!ELEMENT subject (#PCDATA)> <!ELEMENT date (#PCDATA)> <!ELEMENT first_name (#PCDATA)> <!ELEMENT last_name (#PCDATA)> <!ELEMENT people (person*)> <!ELEMENT person (first_name,last_name)> <!ATTLIST event type CDATA #IMPLIED> <!ATTLIST person attendance CDATA #IMPLIED> ]> <events> <event type="informal"> <event_title>National Awards</event_title> <event_number>3</event_number> <subject>Pet Awards</subject> <date>5/5/2007</date> <peoples> <person attendance="present"> <first_name>June</first_name> <last_name>Allyson</last_name> </person> <person attendance="absent"> <first_name>Virginia</first_name> <last_name>Mayo</last_name> </person> <person attendance="present"> <first_name>Jimmy</first_name> <last_name>Stewart</last_name> </person> </peoples> </event> </events>
That DTD lets you check the syntax of your XML document, which is a good thing because there’s an error in this document: the <peoples> element has replaced <people>. But as you can see in Figure 9.9, you can catch this kind of validation error in Ajax applications.
Figure 9.9: Validating an XML document
Here’s how it works. After downloading the XML data in Internet Explorer, you can create an MSXML2.DOMDocument object that will parse your downloaded XML:
function getData() { var XMLHttpRequestObject = false; XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); if(XMLHttpRequestObject) { XMLHttpRequestObject.open("GET", "eventdtd.xml?k=4", true); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { var xmlDocument = XMLHttpRequestObject.responseXML; var parser = new ActiveXObject("MSXML2.DOMDocument"); . . . } }
then you set the parser object’s validateOnParse property to true, and load the XML you’ve already downloaded:
function getData() { var XMLHttpRequestObject = false; XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); if(XMLHttpRequestObject) { XMLHttpRequestObject.open("GET", "eventdtd.xml?k=4", true); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { var xmlDocument = XMLHttpRequestObject.responseXML; var parser = new ActiveXObject("MSXML2.DOMDocument"); parser.validateOnParse = true; parser.load(XMLHttpRequestObject.responseXML); . . . }
After having parsed the XML, you can check the parser.parseError.errorCode property, and if it’s not 0, there was an error. You can get more data about the error with the parseError properties such as line, url, errorCode, and srcText:
function getData() { var XMLHttpRequestObject = false; XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); if(XMLHttpRequestObject) { XMLHttpRequestObject.open("GET", "eventdtd.xml?k=4", true); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { var xmlDocument = XMLHttpRequestObject.responseXML; var parser = new ActiveXObject("MSXML2.DOMDocument"); parser.validateOnParse = true; parser.load(XMLHttpRequestObject.responseXML); var target = document.getElementById("targetDiv"); if (parser.parseError.errorCode != 0) { target.innerText = "Error in " + parser.parseError.url + " line " + parser.parseError.line + " position " + parser.parseError.linepos + ".\nError source: " + parser.parseError.srcText + "\n" + parser.parseError.reason + "\n" + "Error: " + parser.parseError.errorCode; } else { displayThirdGuest(xmlDocument); } } } XMLHttpRequestObject.send(null); } }
Handling XML documents like this lets you check their validity.