MozillaZine

XPath

From MozillaZine Knowledge Base

(Difference between revisions)
Revision as of 21:59, 18 March 2005
Grimholtz (Talk | contribs)
(oops - bad formatting)
<-- Previous diff
Revision as of 23:30, 18 March 2005
Asqueella (Talk | contribs)
(Wrapper function - stylistic changes)
Next diff -->
Line 15: Line 15:
function evaluateXPath(aNode, aExpr) { function evaluateXPath(aNode, aExpr) {
var xpe = new XPathEvaluator(); var xpe = new XPathEvaluator();
- var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ? aNode.documentElement :+ var nsResolver = xpe.createNSResolver(aNode.ownerDocument ?
- aNode.ownerDocument.documentElement);+ aNode.ownerDocument.documentElement : aNode.documentElement);
var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null); var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
var found = []; var found = [];

Revision as of 23:30, 18 March 2005

XPath is a language for addressing parts of an XML document. It is a W3C recommendation.

This article describes Mozilla interfaces exposing XPath functionality to Javascript code. These are described in DOM Level 3 XPath (which is W3C Working Group Note at this moment).

This article does not attempt teach XPath itself. If you're unfamiliar with this technology, please refer to W3Schools XPath tutorial.

Wrapper function

The following function can be used to evaluate XPath expressions on given XML nodes. The first argument is a DOM node, while the second is a string defining an XPath expression.

// Evaluate an XPath expression aExpression against a given DOM node
// or Document object (aNode), returning the results as an array
// thanks wanderingstan at morethanwarm dot mail dot com for the
// initial work.
function evaluateXPath(aNode, aExpr) {
  var xpe = new XPathEvaluator();
  var nsResolver = xpe.createNSResolver(aNode.ownerDocument ?
       aNode.ownerDocument.documentElement : aNode.documentElement);
  var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
  var found = [];
  while (res = result.iterateNext())
    found.push(res);
  return found;
}

Sample Usage

Assume we have the following XML document (see also How to Create a DOM tree and Parsing and serializing XML) and people is the <people> element:

<?xml version="1.0"?>
<people>
  <person first-name="eric" middle-initial="H" last-name="jung">
    <address street="321 south st" city="denver" state="co" country="usa"/>
    <address street="123 main st" city="arlington" state="ma" country="usa"/>
  </person>

  <person first-name="jed" last-name="brown">
    <address street="321 north st" city="atlanta" state="ga" country="usa"/>
    <address street="123 west st" city="seattle" state="wa" country="usa"/>
    <address street="321 south avenue" city="denver" state="co" country="usa"/>
  </person>
</people>

You can now "query" the document with XPath expressions. Although walking the DOM tree can achieve similar results, using XPath expressions is much quicker and more powerful. If you can rely on id attributes, document.getElementById() is still powerful, but it's not nearly as powerful as XPath. Here are some examples.

// display the last names of all people in the doc
var results = evaluateXPath(people, "//person/@last-name");
for (var i in results)
  alert("Person #" + i + " has the last name " + results[i].value);

// get the 2nd person node
results = evaluateXPath(people, "/people/person[2]");

// get all the person nodes that have addresses in denver
results = evaluateXPath(people, "//person[address/@city='denver']");

// get all the addresses that have "south" in the street name
results = evaluateXPath(people,  "//address[contains(@street, 'south')]");
alert(results.length);

Resources