Document Loading States and Validation

only for RuBoard

This section discusses an application that loads an XML document asynchronously and validates it against a DTD. Listing 5.2 shows the XML document manycustomers.xml , which contains 225 customer elements. This document also contains an internal DTD because you will validate this document against the DTD.

Note

For the sake of brevity, Listing 5.2 shows a single customer element.


Listing 5.2 A Customer's XML Document That Contains 255 Customer Elements
 <?xml version="1.0" encoding="utf-8" ?>  <!DOCTYPE Customers [      <!ELEMENT Customers (Customer)* >       <!ELEMENT Customer (CompanyName,Contact)  >       <!ATTLIST Customer                 id  CDATA  #REQUIRED >       <!ELEMENT CompanyName (#PCDATA)  >       <!ELEMENT Contact (FirstName , LastName , Title  )  >       <!ELEMENT FirstName (#PCDATA)  >       <!ELEMENT LastName (#PCDATA)  >       <!ELEMENT Title (#PCDATA)  >  ]>  <Customers>       <Customer id="ALFKI">            <CompanyName>Alfreds Futterkiste</CompanyName>            <Contact>                 <FirstName>Maria</FirstName>                 <LastName>Anders</LastName>                 <Title>Sales Representative</Title>            </Contact>       </Customer>  .  .  .  </Customers> 

Listing 5.3 shows the JavaScript code that sets the event handlers for the events onreadystatechange and ondataavailable . You can do this by setting the corresponding properties onreadystatechange and ondataavailable respectively of the DOMDocument object.

Listing 5.3 The HTML Page for the Loading ( parseevents.htm )
 <html>       <head>            <title>Parser Events</title>       </head>       <body>            <div id="state">            </div>            <div id="data">            </div>       </body>  </html>  <script language="javascript">  var LOADING          = 1;  var LOADED          = 2;  var INTERACTIVE = 3;  var COMPLETED   = 4;  state.innerHTML = "<B>Data Loading State</B><BR>";  data.innerHTML = "<B>Data Available State</B><BR>";  var objXML = new ActiveXObject("MSXML2.DOMDocument.4.0") ;  objXML.async = true;  objXML.validateOnParse= true;  objXML.onreadystatechange = readyStateChangeHandler;  objXML.ondataavailable       =     dataAvailableHandler ;  objXML.load("manycustomers.xml");  function getTime(currDate)  { var time =  currDate.getMinutes()       + ":" + currDate.getSeconds()       + "." + currDate.getMilliseconds();  return time;  }  function  readyStateChangeHandler()  {      var  currDate = new Date();       var time = getTime(currDate);       state.innerHTML += "Time: " + time + " State: ";       switch(objXML.readyState)       {           case LOADING :                 state.innerHTML += "The loading is in progress.<BR>";                 break;            case LOADED :                 state.innerHTML += "The document is loaded.<BR>";                 break;            case INTERACTIVE :                 state.innerHTML +=  "The object model is available as read-                only.<BR>";                 break;            case COMPLETED:                 state.innerHTML +=  "The document has been " +                      "completely loaded, successfully or unsuccessfully.<BR>";                 if (objXML.parseError.errorCode != 0)                 {                     state.innerHTML += getErrorMsg(objXML.parseError);                 }                 else                 {                     state.innerHTML += "<BR><B>The XML document was loaded "                           + "successfully</B><BR><BR>";                 }                 break;       }  }  function getErrorMsg( objError)  {      var strError = "";       strError +=  "<BR><B>The XML document was not loaded "            + "successfully...</B><BR> ";       strError +=      "The URL  '"+ objError.url  + "' contained "            + "the following error <BR>";       strError +=      "<B>" + objError.reason +     "Line "            + objError.line + ", Position "            + objError.linepos + ".</B><BR>";       strError +=  objError.srcText + "<BR>";       return strError;  }  function dataAvailableHandler()   {      var currDate = new Date();       var time = getTime(currDate);       data.innerHTML += "Time: " + time + "     Data Available :" +            objXML.documentElement.childNodes.length + " nodes. <BR>";  }  </script> 

The DOM specification leaves the approach of loading and saving the document to the DOM implementations . MSXML provides two extensions to the DOM API: the load method and the async property (which loads a document into the DOM). Setting the async property to true forces the load method to return the control to the caller before the document is completely downloaded. This enables you to do other things while the document loads. This feature is called asynchronous loading because, if you set it to false, the control returns only after the document finishes loading.

In this example, you set the async property to true so that you can examine the parser events. You attached an onreadystatechange event handler called readyStateChangeHandler that gets called when the parser's ready state changes. The parser can be in one of the four ready states: loading , loaded , interactive ,or completed . The method readyStateChangeHandler() checks these parser states from the readyState property and displays them to the browser by using the DHTML innerHTML property.

After the parser is in the completed state, it does not mean that document loading was successful. The ParseError object holds information about the most recent parse error that might have occurred during the loading. You must check this property to find out whether the document was loaded successfully and display the error messages, if any, through the getErrorMsg method. You set the validateOnParse property to true before calling the load method. This makes the parser validate the document against a DTD and report any errors through the ParseError object.

The loading states and the error message are displayed, as shown in Figure 5.2.

Figure 5.2. The parser ready states and error notification.
graphics/05fig02.gif

Now look at the ondataavailable event handler that I repeated in the following code:

 function dataAvailableHandler()   {      var currDate = new Date();       var time = getTime(currDate);       data.innerHTML += "Time: " + time + "     Data Available :" +            objXML.documentElement.childNodes.length + " nodes. <BR>";  } 

The method dataAvailableHandler() is the event handler for the ondataavailable event. This method is called when the data becomes available to the parser. This allows you to work with the data or display it to the client as soon as it is available. This saves the wait time for the client, in the case of large XML documents using the synchronous loading technique. In this example, the number of nodes loaded is displayed with the time shown. Figure 5.3 shows the output after all the 225 nodes are loaded.

Figure 5.3. The parser ready states and the stages in which data is available after a document is successfully loaded.
graphics/05fig03.gif

Notice that, from the time the ready state is interactive to the time it is complete, almost all the data becomes available to the parser. So you don't have to wait for the entire document to load before you start working with the data. Therefore, in the case of large documents, by setting the async property to false, the user must wait until the entire file downloads to the client machine. The transformation to HTML using XSLT or through the JavaScript program adds more waiting time for the user. On the other hand, with asynchronous download, the user can see the display immediately after data is available to the parser.

only for RuBoard


XML and ASP. NET
XML and ASP.NET
ISBN: B000H2MXOM
EAN: N/A
Year: 2005
Pages: 184

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net