Tutorial Categories:

HTML/CSS JavaScript/AJAX Server-Side Marketing General Comp-Sci

An Introduction to DOM Objects and JSON

By Justin Poirier

In a user agent's source code, and in interpreted code run inside the user agent, the object type used to represent an XML document's tree of elements and the attributes of those elements is called a Document Object Model (DOM) tree. The DOM tree contains a node for not only all elements in the XML, but all attributes as well. The node for an attribute is a child of that of the element to which it belongs. The DOM tree most often accessed is that of the XML document (often HTML) currently open in the user agent. In JavaScript, this DOM tree can be accessed through the system variable "document". In addition to the DOM tree of the document currently open, scripts will often have to deal with a DOM tree generated from some other XML data, as in the case of XML that has been returned from the server in response to an AJAX request.

The following DOM object member functions and variables are visible to code operating on the object, and are used to access nodes of the object. The code may be written in any of several languages including JavaScript. The functions/variables offer various ways of specifying the desired node(s). As each node in the DOM tree is itself a DOM tree containing its 0 or more children, these functions/variables exist as members of all nodes. While attributes, as mentioned, become nodes in the DOM tree, they are not returned by any of these functions/variables other than "attributes[]". The nodes created for attributes do contain these functions/variables, but the only ones that would not return null when called in an attribute node are "nodeName" and "nodeValue". For the most part, the purposes of these functions/variables are self-explanatory.

getElementsByTagName(Tag name) This function returns an array.
getElementById(Id)
firstChild
lastChild
childNodes This function returns an array.
parentNode
attributes[]
nodeName When the node represents an element, this is the type of the element. When it represents an attribute, this is the name of the attribute. This is not the name of an element as set by the "name" attribute.
nodeValue When the node represents an element, this is the content of the element. When it represents an attribute, this is the value that has been assigned to the attribute.

For a full list of DOM functions/variables, see the official W3C specification of the DOM.

It is important to recall that for any text between the opening and closing tags of an element ("anonymous text"), for example the word "hello" in the XML code <greeting>hello</greeting>, an anonymous element will automatically be created by the user agent and therefore there will be a node in the DOM tree for this text, separate from the parent element.

For data sets other than the markup of the document currently open, it is often desirable to use a different format and object model than XML and the DOM, respectively. For example, in the JavaScript Object Notation (JSON) format, the objects being represented by the data can be given relationships beyond the parent-child relationship to which object representations in XML are limited1, so the data can often be described in a way that translates directly to the collection of objects used by an object-oriented script. This has obvious advantages over simply generating a DOM tree from XML data, as the objects used are named after what they actually represent and allow faster access to the data than traversing a DOM tree using the functions/variables described earlier.

A JSON document contains a tree-like structure where each node is a syntactical representation of an object with the following format:

{	property 1:value 1,
	property 2:value 2,
	...}

Property names must be enclosed in quotation marks. A value may be a string (in which case it must be enclosed in quotation marks), a number, a boolean (true or false), an array (with values comma-delimited and enclosed in square brackets), null, or another object. It is by assigning an object to another object's property that nesting occurs and the tree-like structure2 is formed.

An example JSON document follows, with a root, and two children of the root.

{
	"team name" : "The Bears",
	"roster-size" : 26,
	"coach":	{
				"name" : "Joe Blow",
				"salary" : 200 000
			},
	"GM" :		{
				"name" : "Even Steven",
				"salary" : 250 000
			}
}

While JSON is a general-purpose format for storing textual data, it has a particularly useful characteristic when JavaScript is the language used in the script interested in the data: JSON data is valid JavaScript code. Before JSON existed, the format it uses was added to ECMAScript, the language created to be a standard-setting language from which subsequent versions of JavaScript could be derived, and to JavaScript itself. In JavaScript code, describing a conceptual object in this format is a way of instructing the interpreter to create and return a JavaScript object for the conceptual object, with a member variable for each of its properties set equal to the appropriate value. If the value of a property is another object, another JavaScript object will be created for it, and so on recursively.

An example usage of this format as JavaScript code follows.

var person = {"name" : "Joe Blow"};

This sets the "person" variable to an object with one member variable, "name", equal to the string "Joe Blow". The member variable can be accessed in the standard way, with the code person.name.

When a script deals with JSON-formatted data, it will most often have been retrieved from some other file as opposed to being part of the script itself. This is the case for data retrieved using an AJAX request. Regardless of the method of retrieval, after retrieving such data, it will only be known to the script as a string. In order to get the interpreter to consider the string as source code, and thus build the JavaScript objects from it as described, the "eval()" function can be used. This function causes the interpreter to execute the string passed to it as a parameter, as code. By passing a string of JSON-formatted data to this function, the data will be used to build objects. For this to work, the string must have opening and closing parenthesis appended to the beginning and end of it, respectively.

An example usage of the eval() function to build objects follows. The example assumes an AJAX request for JSON-formatted data has been made using a request object called requestObject, and the response has been received.

var JoeBlow = eval('(' + requestObject.responseText + ')');

It should be noted that because the eval() function causes the passed code to be executed, it should only be used with JSON data when that data comes from a trusted source. Otherwise, a third-party JSON parser should be used instead.

1 This support is limited due to the fact that JSON data, like XML data, is serial. While a relationship between two objects can have any name, the relationships that can be made are limited by the fact that a relationship is indicated syntactically by nesting one object's description inside the other's. A truly relational format is YAML Ain't a Markup Language (YAML).
2 Whether the structure is an actual tree is ambiguous, since in addition to simple cases of an object being assigned as the single value of a property of another object, an object can exist in an array.