CSE 190M Web Programming

Lecture 19: XML/JSON

Reading: Chapter 12

Except where otherwise noted, the contents of this document are Copyright 2012 Marty Stepp, Jessica Miller, Victoria Kirst and Roy McElmurry IV. 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
	TO: Alice Smith (alice@example.com)
	FROM: 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">
	<to>Alice Smith (alice@example.com)</to>
	<from>Robert Jones (roberto@example.com)</from>
	<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 -->
	<to>Alice Smith (alice@example.com)</to>
	<from>Robert Jones (roberto@example.com)</from>
	<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
$.get("foo.xml")
	.done(functionName);

function functionName(xmlDom) {
	// do stuff with the xmlDom just like you would with the HTML dom
}

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 manually

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");

Full list of XML DOM properties

XML DOM and jQuery

You use the same jQuery functions to interact with the XML DOM, with one minor tweak:

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?
$(xmlDom).find("lawyer").attr("money");	// "99999.00"

// array of 2 janitors
var janitors = $(xmlDom).find("janitor");
janitors.find("vacuum").attr("model");		// "Hoover"
janitors.last().text();										// "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
$(xmlDom).find("book[category='computer']").each(function(idx, e) {
	// extract data from XML
	var title = $(e).find("title").text();
	var author = $(e).find("author").text();

	// make an HTML <p> tag containing data from XML
	$("<p>")
		.text(title + ", by " + author)
		.appendTo($(document.body));
});

Exercise: Animal Game

The Animal Game
  • Write a program that guesses which animal the user is thinking of. The program will arrive at a guess based on the user's responses to yes or no questions. The questions come from a web app named animalgame.php.

Exercise: Animal Game (cont'd)

  • Questions we should ask ourselves:
    • How do I retrieve data from the web app? (what URL, etc.)
    • Once I retrieve a piece of data, what should I do with it?
    • When the user clicks "Yes", what should I do?
    • When the user clicks "No", what should I do?
    • How do I know when the game is over? What should I do in this case?

Exercise: Animal Game (cont'd)

  • The data comes in the following format:
    		<node nodeid="id">
    			<question>question text</question>
    			<yes nodeid="id" />
    			<no nodeid="id" />
    		</node>
    
    		<node nodeid="id">
    			<answer>answer text</answer>
    		</node>
    
  • to get a node with a given id: animalgame.php?nodeid=id
  • start by requesting the node with nodeid of 1 to get the first question

Debugging response XML 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)

Bad style: the eval function

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

JSON expressions exercise

var data = JSON.parse(jsonString);
{
	"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 and AJAX (AJAJ?...)

$.get("foo.json")
	.done(functionName);

function functionName(jsonObj) {
	// do stuff with the jsonObj
}

Exercise: Books

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

Exercise: Books (cont'd)

Write a page that processes this JSON book data.

  • Initially the page lets the user choose a category, created from the JSON data.
  • After choosing a category, the list of books in it appears:
    Books in category "Cooking":
    • Breakfast for Dinner, by Amanda Camp (2009)
    • 21 Burgers for the 21st Century, by Stuart Reges (2010)
    • The Four Food Groups of Chocolate, by Victoria Kirst (2005)