Wrox Home  
Search
Professional JavaScript for Web Developers
by Nicholas C. Zakas
April 2005, Paperback


Excerpt from Professional JavaScript for Web Developers

XPath Support in Browsers

By Nicholas C. Zakas

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.

For instance, consider the following XML document:

<?xml version="1.0"?>
<employees>
    <employee title="Software Engineer">
        <name>Nicholas C. Zakas</name>
    </employee>
    <employee title="Salesperson">
        <name>Jim Smith</name>
    </employee>
</employees>

And consider this XPath expression:

employee/name

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.

If you'd like to learn more about XPath, consider picking up XPath 2.0: Programmer's Reference (Wrox., ISBN 0-7645-6910-4).

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:

var oElement = oXmlDom.documentElement.selectSingleNode("employee/name");

The selectSingleNode() method returns an Element as the function value if found, otherwise it returns null.