XPath, unleashed — coming to Internet Explorer 5+ HTML DOM near you
document.evaluate(expression, contextNode, resolver, type, result);
You’ll find the details of implementation over at the w3.org or mozilla.org, but for starters, expression is the XPath expression string and contextNode is the DOM node that you’d like to use as a root. The rest can be (and most often will be) specified as zeros and nulls. For instance, this expression will get you all div nodes that have class attribute set to DateTime in your document:
var iterator = document.evaluate(”//div[@class='DateTime']”, document, null, 0, null);
By default, the method returns an iterator, which can be worked through like so:
while(item = iterator.iterateNext())
// do something with item
As you might’ve guessed, the iterator returns null once all items are exhausted. By modifying the type parameter, you can make the method return other types, such as string, boolean, number, and a snapshot. Snapshot is kind of like an iterator, except the DOM is free to change while the snapshot still exists. If you try to do the same with the iterator, it will throw an exception.
1) As call to an Msxml.DOMDocument object, created using the new ActiveXObject() statement.
2) If an HTML document was generated as a result of a client-side XSL transformation from an XML file.
Now counting all links on your document is just one XPath query:
var linkCount = document.evaluate(“count(//a[@href])“, document, null, XPathResult.NUMBER_TYPE, null).getNumberValue();
So is getting a list of all images without an alt tag:
var imgIterator = document.evaluate(“//img[not(@alt)]“, document, null, XPathResult.ANY_TYPE, null);
So is finding a first LI element of al UL tags:
var firstLiIterator = document.evaluate(“//ul/li“, document, null, XPathResult.ANY_TYPE, null);
I must say, I haven’t been able to resolve all implementation issues yet. For example, I couldn’t find a pretty way to implement properties of XPathResult. How do you make a property accessor that may throw an exception in JScript? As a result, I had to fall back to the Java model of binding to properties.
So guys, take a look. I can post more on details of implementation, if you’d like. Just let me know.