|
|
IV.9. Blending XML Data into HTML PagesWith recent browsers, you have at your disposal the power to "include" XML data from the same domain into a Web page. The retrieval process occurs behind the scenes, where scripts load XML-formatted data into a virtual document. From there, your client-side scripts can inspect the XML document tree and perform scripted transforms of the data to generate familiar HTML constructs, such as tables. The engine behind this power is a global object called XMLHttpRequest. Online Section II is dedicated to this object's features, so I'll only introduce some of the details here as a way to demonstrate how to convert incoming XML data into renderable HTML content. IV.9.1. Embedding XML DataFor this demonstration, I'll use the same raw Super Bowl results data used earlier for dynamic tables, but this time formatted as an external XML document, rather than embedded JavaScript objects. The XML data will be retrieved in its native state, and then parsed to extract values that ultimately render inside an HTML table. Let's start with the XML document. Although this example loads the data from a file, the data could just as easily arrive from a server process (e.g., database lookup) that returns data with an appropriate XML content type. The structure of the XML file for this demonstration is as follows: <?xml version="1.0"?> <results> <bowl> <number>I</number> <year>1967</year> <winner>Packers</winner> <winscore>35</winscore> <loser>Chiefs</loser> <losscore>10</losscore> </bowl> <bowl> ... </bowl> ... </results> This structure is fairly typical of XML returned from a database lookup in that the bulk of the meaningful data consists of multiple containers (the bowl elements here) that are, themselves, contained within an outer element (the results element here). It's also common for an XML document to contain a section of elements (akin to an HTML document's head element) that convey information about the query. The focus here, however, is on the set of "records" within the data. IV.9.2. Retrieving the XMLBecause of different implementations of the XMLHttpRequest object (an ActiveX object in IE 5, 5.5, and 6; a native global object beginning with IE 7, Mozilla 1.0, Safari 1.2, and Opera 8), the code that loads an external XML data source requires some branching based on object detection. In all cases, the code generates an instance of the XMLHttpRequest object. For the sake of simplicity in this example, that instance is preserved as a global variable named req (a more object-oriented approach is demonstrated in Online Section VII). The following loadXMLDoc( ) function performs a few key operations. First, it creates an instance of the XMLHttpRequest object in the manner supported by the current browser. Second, it assigns a function reference to an event property of the request objectthe handler to run after the XML data has finished loading. Finally, the function sets the request parameters, followed by actually sending the request to the URL passed as a parameter to the loadXMLDoc( ) function. var req; function loadXMLDoc(url, loadHandler) { req = null; // branch for native XMLHttpRequest object if(window.XMLHttpRequest) { try { req = new XMLHttpRequest( ); } catch(e) { req = null; } // branch for IE/Windows ActiveX versions } else if(window.ActiveXObject) { try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { req = null; } } } if(req) { req.open("GET", url, true); req.onreadystatechange = loadHandler; req.setRequestHeader("Content-Type", "text/xml"); req.send(""); } } IV.9.3. Parsing the XML DocumentExample IV-10 contains the entire listing for this example. The drawTable( ) function operates only if the readyState property of the req object is the value (4) indicating that loading has completed. Then the function extracts the root document node object from the req object by way of the responseXML property. In other words, the xDoc local variable is now the equivalent of a document object, but for the unseen XML document retrieved from the server.
The drawTable( ) function knows about the structure of the XML document, and begins its parsing by obtaining a reference to the outermost container of records, the results element. As you can see from the XML file shown earlier, the results element consists of multiple bowl child elements, each representing a single record. Looping through all child nodes of results (and working only with those nodes that are elements and not whitespace, that is, nodes whose nodeType property is 1), a table row's cells are populated by individual text nodes from elements within each record. Elements are referred to by their tag names, rather than their position within the record so that additions or reordering of elements within the XML output won't affect the distribution of data within the table. Example IV-10. Embedding external XML data
IV.9.4. Converting XML to JavaScript ObjectsOne point you can deduce from comparing Examples IV-9 and IV-10 is that if you wish to re-sort the table data without reloading the page, it is far easier and more efficient to use the sorting facilities of JavaScript arrays than it is to manipulate XML data. As a result, you may find it more convenient to convert external XML data into more convenient arrays of JavaScript objects. The typical regularity of XML data greatly simplifies and speeds the creation of the JavaScript counterparts. Example IV-11 shows a function that converts the XML data file from Example IV-10 to corresponding JavaScript data objects. Example IV-11. XML to JavaScript array function
With the data in this format, you can apply the sorting facilities from Example IV-9 to the data. |
|
|