CSSE 290 Web Programming

Lecture 21: XML and JSON

Reading: 12.3, 12.4

Attribution: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.

Otherwise noted: Claude Anderson was given permission to modify the slides for CSSE 290 at Rose-Hulman by author Jessica Miller. The authors' original slides, based on Web Programming Step by Step, can be seen at http://webstepbook.com.
Some of the examples in some days' slides are from David Fisher at Rose-Hulman, who was kind enough to allow me to use them. My intention is to mark these examples with [DSF].

Valid HTML 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
	new Ajax.Request("url", {
		method: "get",
		onSuccess: functionName
	});
	...

function functionName(ajax) {
	do something with ajax.responseXML;
}

XML DOM tree structure

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

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 $ or $$:

var elms = $$("#main li");   $("id");

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

var text = $("foo").innerHTML;

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

var imageUrl = $("myimage").src;

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 = ajax.responseXML.getElementsByTagName("lawyer")[0];
var salary = lawyer.getAttribute("money");      // "99999.00"

// array of 2 janitors
var janitors = ajax.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>

Let's write some code for this example

Textbook example: Animal game

The Animal Game

Animal game (cont'd)

Attacking the problem

Questions we should ask ourselves:

Debugging responseXML in Firebug

Firebug Debug Ajax

Schemas and Doctypes

Pros and cons of XML

JavaScript Object Notation (JSON)

json
json

JavaScript Object Notation (JSON): Data format that represents data as a set of JavaScript objects

Recall: JavaScript object syntax

var person = {
	name: "Philip J. Fry",                           // string
	age: 23,                                         // number
	"weight": 172.5,                                 // number
	friends: ["Farnsworth", "Hermes", "Zoidberg"],   // array
	getBeloved: function() { return this.name + " loves Leela"; }
};
alert(person.age);                                 // 23
alert(person["weight"]);                           // 172.5
alert(person.friends[2]));                         // Zoidberg
alert(person.getBeloved());                        // Philip J. Fry loves Leela

An example of XML 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>
	<to>Charles Dodd (cdodd@example.com)</to>
	<subject>Tomorrow's "Birthday Bash" event!</subject>
	<message language="english">
		Hey guys, don't forget to call me this weekend!
	</message>
</note>

The equivalant JSON data

{
	"private": "true",
	"from": "Alice Smith (alice@example.com)",
	"to": [
		"Robert Jones (roberto@example.com)",
		"Charles Dodd (cdodd@example.com)"
	],
	"subject": "Tomorrow's \"Birthday Bash\" event!",
	"message": {
		"language": "english",
		"text": "Hey guys, don't forget to call me this weekend!"
	}
}

Browser JSON methods

method description
JSON.parse(string) converts the given string of JSON data into an equivalent JavaScript object and returns it
JSON.stringify(object) converts the given object into a string of JSON data (the opposite of JSON.parse)

JSON expressions exercise

var data = JSON.parse(ajax.responseText);
{
	"window": {
		"title": "Sample Widget",
		"width": 500,
		"height": 500
	},
	"image": { 
		"src": "images/logo.png",
		"coords": [250, 150, 350, 400],
		"alignment": "center"
	},
	"messages": [
		{"text": "Save", "offset": [10, 30]}
		{"text": "Help", "offset": [ 0, 50]},
		{"text": "Quit", "offset": [30, 10]},
	],
	"debug": "true"
}

Given the JSON data at right, what expressions would produce:

var title = data.window.title;
var coord = data.image.coords[2];
var len = data.messages.length;
var y = data.messages[len - 1].offset[1];

JSON example: Books

Suppose we have a service books_json.php about library books.

JSON exercise

Write a page that processes this JSON book data.

Working with JSON book data

function showBooks(ajax) {
	// add all books from the JSON data to the page's bulleted list
	var data = JSON.parse(ajax.responseText);
	for (var i = 0; i < data.books.length; i++) {
		var li = document.createElement("li");
		li.innerHTML = data.books[i].title + ", by " +
				data.books[i].author + " (" + data.books[i].year + ")";
		$("books").appendChild(li);
	}
}

Bad style: the eval function

// var data = JSON.parse(ajax.responseText);
var data = eval(ajax.responseText);   // don't do this!
...

HW6 Preview