Because XML is used for so many kinds of data, it became necessary to create a means to locate data inside of XML code. The answer to this problem is XPath, which is a small language used specifically to locate a single node or multiple nodes that match a particular pattern.

Introduction to XPath

Every XPath expression has two parts: a context node and a node pattern. The context node provides the context from which the node pattern should begin. The node pattern is a string made up of one or more node selectors.

If the context node is <employees/>, then the previous XPath expression matches both <name>Nicholas C. Zakas</name> and <name>Jim Smith</name>. In the expression, both employee and name refer to tag names of XML elements in the order in which they appear from the context node; the slash indicates a parent-to-child relationship. In essence, the XPath expression says, "Starting from <employees/>, match any <name/> elements located under any <employee/> element that is a child of the reference node."

To select only the first <employee/> element's <name/> element, the XPath expression is the following:

employee[position() = 1]/name

In XPath, the square brackets notation is used to provide more specific information about an element. This example uses the XPath position() function, which returns the element's position under its parent element. The first child node is in position 1, so comparing position() to 1 matches only the first <employee/> element. Then, the slash and name match the <name/> element under that first <employee/> element.

You can use a variety of ways to match elements in addition to their names and positions. Suppose you want to select all <employee/> elements with the title attribute equal to "Salesperson", the XPath expression would be the following:

employee[@title = "Salesperson"]

In this expression, the @ symbol is short for attribute.

XPath is a very powerful expression that can make finding specific nodes within a DOM Document much easier. Because of this, both IE and Firefox made sure to include XPath support in their DOM implementations.

XPath support in IE

Microsoft saw fit to build XPath support right into the XML DOM object. Each node has two methods that can be used to retrieve nodes matching an XPath pattern: selectNodes(), which returns a collection of nodes matching a pattern, and selectSingleNode(), which returns the first node that matches a given pattern.

Using the same data as the previous section, you can select all <name/> elements that are children of an <employee/> element by using the following code:

var lstNodes = oXmlDom.documentElement.selectNodes("employee/name");

Because selectNodes() is called as a method of oXmlDom.documentElement, the document element is considered the context node for the XPath expression. The method returns a NodeList containing all elements that match the given pattern, meaning that you can iterate through the elements like so:

for (var i=0; i < lstNodes.length; i++) {
alert(lstNodes[i]);
}

Even if there are no matches to a given pattern, a NodeList is still returned. If it is empty, its length property is equal to 0.

The result of selectNodes() is a living list. So, if you update the document with another element that matches the XPath expression, that element is automatically added to the NodeList in the appropriate position.

If you want only the first element matching the pattern, then selectSingleNode() is the method to use:

XPath Support in Browsers

WEBINAR:On-Demand

XPath support in Firefox

As you may have guessed, Firefox supports the XPath according to the DOM standard. A DOM Level 3 addition called DOM Level 3 XPath defines interfaces to use for evaluating XPath expressions in the DOM. Unfortunately, this standard is more complicated than Microsoft's fairly straightforward approach.

Although a handful of XPath-related objects exist, the two most important ones are XPathEvaluator and XPathResult. An XPathEvaluator is used to evaluate an XPath expression with a method named, appropriately enough, evaluate().

The evaluate() method takes five arguments: the XPath expression, the context node, a namespace resolver, the type of result to return, and an XPathResult object to fill with the result (usually null). The third argument, the namespace resolver, is necessary only when the XML code uses an XML namespace, and so typically is left as null. The fourth argument, the type of result to return, is one of 10 constants values:

XPathResult.ANY_TYPE — Returns the type of data appropriate for the XPath expression

XPathResult.ANY_UNORDERED_NODE_TYPE — Returns a node set of matching nodes, although the order may not match the order of the nodes within the document

XPathResult.BOOLEAN_TYPE — Returns a Boolean value

XPathResult.FIRST_ORDERED_NODE_TYPE — Returns a node set with only one node, which is the first matching node in the document

XPathResult.NUMBER_TYPE — Returns a number value

XPathResult.ORDERED_NODE_ITERATOR_TYPE — Returns a node set of matching nodes in the order in which they appear in the document. This is the most commonly used result type.

XPathResult.ORDERED_NODE_SNAPSHOT_TYPE — Returns a node set snapshot, capturing the nodes outside of the document so that any further document modification doesn't affect the node list. The nodes in the node set are in the same order as they appear in the document.

XPathResult.STRING_TYPE — Returns a string value

XPathResult.UNORDERED_NODE_ITERATOR_TYPE — Returns a node set of matching nodes, although the order may not match the order of the nodes within the document

XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE — Returns a node set snapshot, capturing the nodes outside of the document so that any further document modification doesn't affect the node set. The nodes in the node set are not necessarily in the same order as they appear in the document.

The type of result you specify determines how to retrieve the value of the result. Here's a typical example:

This example uses the XPathResult.ORDERED_NODE_ITERATOR_TYPE result, which is the most commonly used result type. If no nodes match the XPath expression, evaluate() returns null; otherwise, it returns an XPathResult object. If the result is a node iterator, whether it be ordered or unordered, you use the iterateNext() method repeatedly to retrieve each matching node in the result. When there are no further matching nodes, iterateNext() returns null. Using a node iterator, it's possible to create a selectNodes() method for Firefox:

The selectNodes() method is added to the Element class to mimic the behavior in IE. When evaluate() is called, it uses the this keyword as the context node (which is also how IE works). Then, a result array (aNodes) is filled with all the matching nodes. You can use this new method like so:

The last section of XPathResult types are the Boolean type, number type, and string type. Each of these result types returns a single value using the booleanValue, numberValue, and stringValue properties, respectively. For the Boolean type, the evaluation typically returns true if at least one node matches the XPath expression and returns false otherwise:

This code outputs the number of nodes that match "employee/name" (which is 2). If you try using this method without one of the special XPath functions, numberValue is equal to NaN.

For the string type, the evaluate() method finds the first node matching the XPath expression, then returns the value of the first child node, assuming the first child node is a text node. If not, the result is an empty string. Here's an example:

The previous code outputs "Nicholas C. Zakas", because that is the first text node in the first <name/> element under an <employee/> element.

If you feel like living dangerously, you can use the XPathResult.ANY_TYPE. By specifying this result type, evaluate() returns the most appropriate result type based on the XPath expression. Typically, this result type is a Boolean value, number value, string value, or an unordered node iterator. To determine which result type has been returned use the resultType property:

As you can tell, XPath evaluation in Firefox is much more complicated than IE, but also much more powerful. By using the custom selectNodes() and selectSingleNode() methods, you can perform XPath evaluation in both browsers using the same code.

About the Author

Nicholas C. Zakas has worked in web development for more than five years. He has helped develop web solutions in use at some of the largest companies in the world. Nicholas is also an active blogger on JavaScript and Ajax topics at http://www.nczonline.net/.

Reprinted with permission of the publisher.

About the Author

Nicholas C. Zakas

Nicholas C. Zakas is the lead author of Professional Ajax by (Wrox, 2006, ISBN: 0-471-77778-1) and the author of Professional JavaScript for Web Developers (Wrox, 2005, ISBN: 0-7645-7908-8). He has worked in web development for more than five years. He has helped develop web solutions in use at some of the largest companies in the world. Nicholas is also an active blogger on JavaScript and Ajax topics at http://www.nczonline.net/.

Advertiser Disclosure:
Some of the products that appear on this site are from companies from which QuinStreet receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. QuinStreet does not include all companies or all types of products available in the marketplace.

Thanks for your registration, follow us on our social networks to keep up-to-date