ABC the iSchool



Andy Gravano, iSchool Systems Administrator needs your help in developing an iSchool course web service. At the present moment, however, he has only three experimental XML documents derived from the "webservices.washington.edu/docs/courses" - the Courses API (working document) which has information about course offerings at all UW campuses.

Andy can offer you these three XML documents to use for development:




He wants you to develop a Prototype web page that would illustrate the "proof-of-concept" code. The plan right now is to build a web page that would have a series of buttons across the top - "A", "B", "C", etc. An iSchool student could click a button and the web page would refresh itself.






Some developer notes

Use the Prototype.js library for the AJAX code.

<script src="latest_version_of_prototype_here.js" type="text/javascript"></script>
	

<script type="text/javascript">
		
var myAJAX = new Ajax.Request('YOUR_TARGET_XML_FILE_NAME_HERE',
{	
method:'get',
onSuccess: function(transport){
  var response = transport.responseXML || "no response XML";
  ... call a function to unpack the XML
},
onFailure: function(){ alert('Something went wrong...') }
});
	
</script>

Place the latest version of the prototype library and the three source XML files in the same subdirectory. Create a webpage in the same subdirectory. The design of the webpage is not too important right now, but find yourself three images of the letters, A, B, and C. Here is the design that I used.


The webpage is pretty simple: A DIV with the headings "Course name" and "Department" and then below this DIV there is a table. The table has an ID attribute that you can use to target and then attach the information produced by the HTTPRequest to this table.

<DIV style="font-size: 24px; font-weight: bold;"> <span style="margin-right: 250px">Course name</span>Department </DIV> <table id="showABC"></table>

In developing the web page, it would be clever to make sure that the HTTPRequest is actually working and that you can represent its contents as a nodeset. Here I'm testing the "length" attribute of the nodeset.


var curricula = response.documentElement;
var curriculum = curricula.childNodes;	
alert(curriculum.length);

If you follow my example code above, "curriculum" is a nodeset of curriculum nodes. Each curriculum node is composed of a set of child nodes named "name", "college-fullname" and so on. Here is a snippet of the XML document that you are unpacking.

<?xml version="1.0" standalone="yes"?>
<curricula>
 <curriculum>
  <uri>http://webservices.washington.edu/courses/0.2/Seattle/A%20A</uri>
  <name>A A</name>
  <fullname>AERONAUTICS & ASTRONAUTICS</fullname>
  <campus-name>Seattle</campus-name>
  <department>A A</department>
  <department-fullname>AERONAUTICS & ASTRONAUTICS</department-fullname>
  <college>ENGR</college>
  <college-fullname>COLLEGE OF ENGINEERING</college-fullname>
 </curriculum>
 

The general strategy is fairly straight forward. Build a loop that will expose each child node of curriculum. Build an inner loop that exposes all the child nodes and look for "fullname", "college-fullname", etc. Put these into separate <TD> elments and then the two of them into a <TR> element. Add the <TR> elements to a single big DIV element. When you've finished looping, insert this DIV element as the innerHTML of the <TABLE> element in the webpage.

For you reference, here's some code to build an HTML table

<table border="1" cellpadding="5" cellspacing="5" width="100%">
<tr>

<th>Table header</th>
<th>Table header</th>

</tr>

<tr>
<td width="20%">Table cell 1</td><td>Table cell 2</td>
</tr>
</table>

Dogs Cats
A DogA Cat

A suggested looping

I targeted the table node with the ID "showABC". Then cycled through the curriculum nodes. For each curriculum node, I created a new TR element and then exposed the "fullname" node and put it in a new TD node. Then I exposed the "college-fullname" and put it in a new TD node. Then I added these two new TD nodes to the TR node. Once you have loaded the two new TD nodes to the TR node, you can add the TR node to the collector DIV.

Eventually, you can give the innerHTML of the DIV node to the innerHTML to your table element with the ID "showABC".

// Target the table element
var q = document.getElementById("showABC");

// Create a DIV that will become the tables innerHTML
var tableContents = document.createElement("DIV");

// The basic loop through the nodeset

for (var i = 0; i < YOUR_NODESET_ELEMENT.length; i++)

// Get the childnodes of YOUR_NODESET_ELEMENT[i]
var aspects = YOUR_NODESET_ELEMENT[i].childNodes

// Create a table row element
var p = document.createElement("tr");

// Test that the nodeName is "fullname"
See note below for origin of "aspects"
if (aspects[j].nodeName == "fullname")
// Collect the "fullname" as content for a table data element
var td1 = document.createElement("td");

// Add the table data element to the table row
p.appendChild(td1);

// Test that the nodeName is "college-fullname"
if(aspects[j].nodeName == "college-fullname")
// Collect the "college-fullname" as content for a table data element
var td2 = document.createElement("td");
// Add the table data element to the table row
p.appendChild(td2);

// Add the table row to the table contents DIV
tableContents.appendChild(p);

// Give the tableContents to the table element

q.innerHTML = tableContents.innerHTML;

When you harvest the information from the "fullname" and "college-fullname" nodes, recognize that the text value you want is the firstChild text value of the node.


var aspects = curriculum[i].childNodes;
...
aspects[j].nodeName == "fullname"
...

var thisTableNode = document.createElement("td");
var thisTableNodeValue = document.createTextNode(aspects[j].firstChild.nodeValue);
thisTableNode.appendChild(thisTableNodeValue);


Demo display of node value

function zango(response)
{
    var curricula = response.documentElement;
    var curriculum = curricula.childNodes;	
    var aspects = curriculum[7].childNodes;
	
    //alert(aspects.length);
	
    for (var h = 0; h < aspects.length; h++)
    {
      if (aspects[h].nodeName == "department")
      {
        alert(aspects[h].firstChild.nodeValue);
      }
    }

}