Topic 3

The Document Object Model and XML Parsing in AJAX

Today we will combine the topics of the first two weeks, by examining how we can connect to a web service from an AJAX-based front end. We will connect to a web service from AJAX and then parse or interpret the XML returned. XML parsing can be made easier through the use of frameworks such as jQuery (which we will look at next week) but this week, we will examine the standard DOM method of XML parsing as it is an important concept to be aware of.

Querying and Manipulating HTML and XML documents using the DOM

So far, we've seen the innerHTML property which can be used to read, or change, the text within an HTML element. However that's just the start: the DOM offers a whole range of ways to read and manipulate HTML pages or XML data. To understand how you can use DOM for document manipulation, you must understand the concept of nodes, which we will discuss below. The examples below use the DOM to manipulate HTML documents, however, more generally, the DOM is used for accessing and manipulating XML documents. An HTML web page is a particular, specific type of XML document. So, as well as using the DOM to query and manipulate web pages, we can use it in a more general sense to query and manipulate XML. In AJAX, this latter use of the DOM is used extensively.

The Concept of Nodes

Example of Nodes Terminology

<body>

<p> Welcome to the <em>wonderful!</em> world of dynamic text!</p>
</body>
  • The paragraph is a child node of the body
  • The paragraph contains three of its own child nodes:
  • The em itself contains one child node:
  • Nodes Hierarchy Diagram: Tree view

    <body>
    <p> Welcome to the <em>wonderful!</em> world of dynamic text!</p>
    
    </body>
    
    Nodes

    Querying the Node Structure of a Document

    Example

    Adding a new node

    Example

    Replacing an existing node

    Example

    Getting all elements of a particular type

    Example

    Removing nodes

    Other useful features of the DOM

    (Source: Quirksmode, a very useful reference site for JavaScript and the DOM)


    Using the DOM to Parse XML in an AJAX application

    The first AJAX example from last time communicates with a server side script which sends back plain text. However, more frequently, the server side component of an AJAX application will send back XML data. In other words, the server side component of an AJAX application is often a web service. The callback function will then parse (interpret) the XML, using the DOM, and integrate the data within the website s front end. Using XML allows us to structure the data, meaning that we can be very flexible in how we present it to the end user we can extract the data we need from the XML (which may not necessarily be all of it) and arrange it on the page how we like.

    This process of extracting the relevant data is called parsing XML. As you will see below, we use the DOM node manipulation functions, discussed above, to parse the XML.

    The DOM feature which is most useful to us in doing this is getElementsByTagName() , which takes a particular tag name and returns an array of all tags with that name. For example imagine the server sent back the results of search for flights to Paris on 1/7/08 as this XML:

    <flights>
    <flight>
    <destination>Paris</destination>
    <number>1</number>
    <time>0900</time>
    <date>1/7/08</date>
    </flight>
    <flight>
    <destination>Paris</destination>
    <number>3</number>
    <time>1400</time>
    <date>1/7/08</date>
    </flight>
    </flights>
    
    The example below would parse XML in the above format in the callback:
    
    
    
    
    
    
    
    

    Mega Airways! - Europe's top value airline!

    SPECIAL IBIZA OFFER!!!!!!!!!!!!!!!!!!!!

    Fly all the way to Ibiza for only GBP5!!!!!!!

    Excludes baggage fee of GBP100 per bag, weight limit 1kg, increasing by GBP50 per kg. Quoted price only valid for the 4am flight from Biggin Hill Airport on January 17th in leap-years ending with an 8. Normal price GBP500, excluding baggage fees as quoted above. The Ibiza airport we fly into is Ibiza(Valencia) Airport, mainland Spain, only a few hours away by boat. Equipment: early 1950s Boeing. Toilet fee of GBP10 on board.

    Destination:
    Date:

    ]]>

    So how is this working? Well, first we get an array of all the flight tags within the XML. We do this using

    var flightsArray = xmlHTTP.responseXML.getElementsByTagName("flight");
    
    xmlHTTP.responseXML represents the XML returned from the server. As seen above, getElementsByTagName() will give us an array of all the tags so this code will extract all the flight tags from the returned XML and place them in the array flightsArray. The tags are represented as JavaScript objects (see last week). So flightsArray will be an array of tag objects.

    We then loop through each object representing a flight tag in the array. For each flight tag, we get hold of the number and time tags within it as follows:

    var number = flightsArray[count].getElementsByTagName("number")[0].
                        firstChild.nodeValue;
    
    var time= flightsArray[count].getElementsByTagName("time")[0].
                        firstChild.nodeValue;
    
    

    The syntax might seem a bit more complex than is necessary, so I'll explain it in detail below.

    Firstly, remember that getElementsByTagName() always returns an array of tags even if there is only one tag with that name. In this case, there will only be one tag, because each flight tag contains only one number tag and one time tag. So to extract that single number tag out of our one-member array we would use:

    flightsArray[count].getElementsByTagName("number")[0]
    

    i.e. the first (and only) member of the array of number tag objects.

    However even this isn t exactly what we want. It gives us an object representing the number tag itself. However what we want is not the tag, but the actual text within it, e.g. 101 for flight 101.

    To get that we need to extract the nodeValue of the firstChild of the tag.

    var number=
    flightsArray[count].getElementsByTagName("number")[0].
    firstChild.nodeValue;