[ Team LiB ] Previous Section Next Section

14.8 Converting an XML Node Tree to JavaScript Objects

NN 6, IE 5(Win)

14.8.1 Problem

You want to convert XML data (either loaded from an external file or embedded as an IE/Windows data island) into JavaScript objects for further manipulation by scripts.

14.8.2 Solution

The following XML2JS( ) function assumes a regular, record-like structure to the XML data (or portion of data that is significant to the page). Two parameters are required: a reference to the XML virtual document object (see Recipe 14.4) and the tag name of the XML document's element that is the parent node of the repeated records:

// convert XML data into JavaScript array of JavaScript objects
function XML2JS(xmlDoc, containerTag) {
    var output = new Array( );
    var rawData = xmlDoc.getElementsByTagName(containerTag)[0];
    var i, j, oneRecord, oneObject;
    for (i = 0; i < rawData.childNodes.length; i++) {
        if (rawData.childNodes[i].nodeType =  = 1) {
            oneRecord = rawData.childNodes[i];
            oneObject = output[output.length] = new Object( );
            for (j = 0; j < oneRecord.childNodes.length; j++) {
                if (oneRecord.childNodes[j].nodeType =  = 1) {
                    oneObject[oneRecord.childNodes[j].tagName] = 
                        oneRecord.childNodes[j].firstChild.nodeValue;    
                }
            }
        }
    }
    return output;
}

This function returns an array of JavaScript objects whose property names are the XML tag names, and whose property values are the text nodes of the XML tags.

14.8.3 Discussion

For an example of invoking the function shown in the Solution, consider the World Cup final match XML data file shown in the Discussion in Recipe 14.4. The element acting as the parent to the repeated record-like data is called worldcup. This is the tag name passed as the second parameter to the XML2JS( ) function. Capture the results in a global variable for use any time while the page remains loaded:

var matchData = XML2JS(xDoc, "worldcup");

The results are in the form of a JavaScript array of JavaScript objects. The object for the first record is the same object as if it were defined in JavaScript syntax:

matchData[0] = {loser:"Argentina", losscore:"2", location:"Uruguay", 
                winner:"Uruguay", winscore:"4", year:"1930"};

With the data in JavaScript format, you have substantial flexibility in how you wish to mine the data for rendering in HTML. JavaScript's built-in array sorting capabilities substantially speeds and simplifies sorting the data according (over and above XSL transforms) to any one of the object properties, and then rerendering the sorted data. If you are showing the data in tabular form, Recipe 14.16 demonstrates how to sort the data and redraw the table in an instant, rather than sending the request back to the server for reconstitution of the page.

You might wonder why you'd bother with the conversion process, since you can transform XML data into HTML directly (as in Recipe 14.6). The benefit, as you can see in Recipe 14.16, is the data in a JavaScript array of objects is much easier to access through scripts. Moreover, you can take advantage of powerful array-sorting routines that would be incredibly clumsy to reproduce using a DOM node tree as the data repository. Making tables that are sortable by a variety of columns is a comparative snap.

14.8.4 See Also

Recipe 14.4 for loading XML data into a page; Recipe 14.6 for converting XML data directly to an HTML table; Recipe 14.16 for sorting dynamically generated tables; Recipe 3.11 for sorting an array of objects.

    [ Team LiB ] Previous Section Next Section