How the DOM Defines the Context for XPath Expressions

The MSXML implementation contains methods that accept an XPath string to conveniently identify nodes within the XML tree. The selectNodes method returns a node list pointing to each of the selected nodes, as in the following example.

items = xmldoc.selectNodes("invoices/invoice/items/item");

It would take a substantial amount of code to retrieve the "item" nodes by walking the tree. With the selectNodes method and XPath expressions, nodes can be retrieved through a single line of code.

In most cases, the returned set of nodes will be iterated over to perform further manipulations. The following example illustrates how you can calculate a total price for an "invoice" element.

function invoiceTotal(invoice)
{
  invoice = invoice.nextNode()
  items = invoice.selectNodes("items/item");
  var sum = 0;
  for (var item = items.nextNode(); item; item = items.nextNode())
  {
    var price = item.selectSingleNode("price").nodeTypedValue;
    var qty = item.selectSingleNode("qty").nodeTypedValue;
    if (qty >= 10)
      price = 0.9*price;
    sum += price * qty;
  }
  return sum;
}

This example contains two query contexts. The first query is performed from the context of the invoice element (invoice), and the query string reflects this by beginning with the document element items. The for... loop iterates through the returned nodes and uses each as a context for further queries. These query strings are relative to item elements, and look within them for the price and qty children. This illustrates that the node upon which the selectNodes is performed defines the context for the query.

Performing queries from the document root versus the document element can be confusing. These two nodes are different in the XML tree and thus require different query strings. The following three statements will yield identical results for the sample document, although only the last two are logically equivalent.

items = xmldoc.selectNodes("invoices/invoice");
items = xmldoc.selectNodes("*/invoice");
items = xmldoc.documentElement.selectNodes("invoice");

The selectSingleNode method returns the first node that matches the query, providing a convenient way to return a node directly without extracting it from a NodeList. It is equivalent to "selectNodes(pattern).item(0)". The preceding example could simplify the code by using the selectSingleNode method.

function invoiceTotal(invoice)
{
  invoice = invoice.nextNode()
  items = invoice.selectNodes("items/item");
  var sum = 0;
  for (var item = items.nextNode(); item; item = items.nextNode())
  {
    var price = item.selectSingleNode("price").nodeTypedValue;
    var qty = item.selectSingleNode("qty").nodeTypedValue;
    sum += price * qty;
  }
  return sum;
}

In this example, selectNodes is still used to select a set of item elements. When only a single node is expected, such as the price and qty elements, selectSingleNode can be used.

See Also

XPath | selectNodes Method | selectSingleNode Method

 Last updated on Saturday, April 10, 2004

© 1992-2003 Microsoft Corporation. All rights reserved.