Web Programming Step by Step, 2nd Edition

Lecture 23: XML

Reading: 12.3, 12.5

Except where otherwise noted, the contents of this document are Copyright 2012 Marty Stepp, Jessica Miller, and Victoria Kirst. All rights reserved. Any redistribution, reproduction, transmission, or storage of part or all of the contents in any form is prohibited without the author's expressed written permission.

Valid HTML5 Valid CSS

Storing structured data in arbitrary text formats (bad)

My note:
BEGIN
	FROM: Alice Smith (alice@example.com)
	TO: Robert Jones (roberto@example.com)
	SUBJECT: Tomorrow's "Birthday Bash" event!
	MESSAGE (english):
		Hey Bob,
		Don't forget to call me this weekend!
	PRIVATE: true
END

XML: A better way of storing data

<?xml version="1.0" encoding="UTF-8"?>
<note private="true">
	<from>Alice Smith (alice@example.com)</from>
	<to>Robert Jones (roberto@example.com)</to>
	<subject>Tomorrow's "Birthday Bash" event!</subject>
	<message language="english">
		Hey Bob, Don't forget to call me this weekend!
	</message>
</note>

What is XML?

Anatomy of an XML file

<?xml version="1.0" encoding="UTF-8"?>      <!-- XML prolog -->
<note private="true">                       <!-- root element -->
	<from>Alice Smith (alice@example.com)</from>
	<to>Robert Jones (roberto@example.com)</to>
	<subject>Tomorrow's "Birthday Bash" event!</subject>
	<message language="english">
		Hey Bob, Don't forget to call me this weekend!
	</message>
</note>

Uses of XML

What tags are legal in XML?

<measure number="1">
	<attributes>
		<divisions>1</divisions>
		<key><fifths>0</fifths></key>
		<time><beats>4</beats></time>
		<clef>
			<sign>G</sign><line>2</line>
		</clef>
	</attributes>
	<note>
		<pitch>
			<step>C</step>
			<octave>4</octave>
		</pitch>
		<duration>4</duration>
		<type>whole</type>
	</note>
</measure>

XML and Ajax

Ajax bleach

Fetching XML using Ajax (template)

node tree
var ajax = new XMLHttpRequest();
ajax.onload = functionName;
ajax.open("GET", url, true);
ajax.send();
...
function functionName() {
	do something with this.responseXML;
}

XML DOM tree structure

node tree
<?xml version="1.0" encoding="UTF-8"?>
<categories> 
  <category>children</category> 
  <category>computers</category> 
  ... 
</categories>

Types of DOM nodes (8.3.1)

<p>
	This is a paragraph of text with a 
	<a href="/path/page.html">link in it</a>.
</p>
DOM Tree

Traversing the DOM tree

every node's DOM object has the following properties:

name(s) description
firstChild, lastChild start/end of this node's list of children
childNodes array of all this node's children
nextSibling, previousSibling neighboring nodes with the same parent
parentNode the element that contains this node

Interacting with XML DOM nodes

node tree

To get a list of all nodes that use a given element:

var elms = node.getElementsByTagName("tag");

To get the text inside of a node:

var text = node.firstChild.nodeValue;

To get an attribute's value from a node:

var attrValue = node.getAttribute("name");

Differences from HTML DOM

Can't get a list of nodes by id or class using getElementById or querySelectorAll:

var elms = document.querySelectorAll("#main li");
document.getElementById("id");

Can't get/set the text inside of a node using innerHTML:

var text = document.getElementById("foo").innerHTML = "hi";

Can't get an attribute's value using .attributeName:

var imageUrl = document.getElementById("myimage").src = "foo.jpg";

Full list of XML DOM properties

Ajax XML DOM example

<?xml version="1.0" encoding="UTF-8"?>
<employees>
	<lawyer money="99999.00" />
	<janitor name="Ed"> <vacuum model="Hoover" /> </janitor>
	<janitor name="Bill">no vacuum, too poor</janitor>
</employees>
// how much money does the lawyer make?
var lawyer = this.responseXML.getElementsByTagName("lawyer")[0];
var salary = lawyer.getAttribute("money");      // "99999.00"

// array of 2 janitors
var janitors = this.responseXML.getElementsByTagName("janitor");
var vacModel = janitors[0].getElementsByTagName("vacuum")[0].getAttribute("model");  // "Hoover"
var excuse = janitors[1].firstChild.nodeValue;  // "no vacuum, too poor"

Larger XML file example

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
	<book category="cooking">
		<title lang="en">Everyday Italian</title>
		<author>Giada De Laurentiis</author>
		<year>2005</year><price>30.00</price>
	</book>
	<book category="computers">
		<title lang="en">XQuery Kick Start</title>
		<author>James McGovern</author>
		<year>2003</year><price>49.99</price>
	</book>
	<book category="children">
		<title lang="en">Harry Potter</title>
		<author>J K. Rowling</author>
		<year>2005</year><price>29.99</price>
	</book>
	<book category="computers">
		<title lang="en">Learning XML</title>
		<author>Erik T. Ray</author>
		<year>2003</year><price>39.95</price>
	</book>
</bookstore>

Navigating node tree example

// make a paragraph for each book about computers
var books = this.responseXML.getElementsByTagName("book");
for (var i = 0; i < books.length; i++) {
	var category = books[i].getAttribute("category");
	if (category == "computers") {
		// extract data from XML
		var title = books[i].getElementsByTagName("title")[0].firstChild.nodeValue;
		var author = books[i].getElementsByTagName("author")[0].firstChild.nodeValue;
		
		// make an HTML <p> tag containing data from XML
		var p = document.createElement("p");
		p.innerHTML = title + ", by " + author;
		document.body.appendChild(p);
	}
}

Exercise: Late day distribution

Exercise: Animal game

The Animal Game

Practice problem: Animal game (cont'd)

Attacking the problem

Questions we should ask ourselves:

Debugging responseXML in Firebug

Firebug Debug Ajax

Schemas and Doctypes