W3C home > Mailing lists > Public > public-webapps@w3.org > October to December 2011

Re: XPath and find/findAll methods

From: Robin Berjon <robin@berjon.com>
Date: Wed, 23 Nov 2011 11:23:42 +0100
Cc: public-webapps WG <public-webapps@w3.org>
Message-Id: <C6CFC293-E612-452A-A0C9-68AF86DD345F@berjon.com>
To: Jonas Sicking <jonas@sicking.cc>
On Nov 23, 2011, at 01:08 , Jonas Sicking wrote:
> I really don't think that selectors can ever compete with the
> expressiveness of XPath. Consider the following expression:
> 
> //div[count(.//span) > 6][count(.//span[@data-foo = ../@data-bar]) mod 2 = 1]
> 
> This expression finds all <div> elements which has at least 6 <span>
> descendants and where an odd number of those <span> elements have a
> "data-foo" attribute equal to its parents "data-bar" attribute. It is
> obviously trivial to add arbitrary additional complexity to this
> expression.
> 
> Trying to do the same thing in Selectors will just result in a
> incomprehensible mess.

That's exactly what worries me with this plan.

> At the same time, XPath can't ever compete in expressiveness to
> Javascript. Finding all <div> elements with a "data-foo" attribute
> that contains a prime number is not possible in XPath but trivial in
> javascript.

Well, for values of trivial that could be quite slow :) But yes.

> I'm not convinced that it's worth investing in XPath. At least not
> beyond the low-hanging fruit of making most of the arguments to
> .evaluate optional. But I think trying to make selectors compete in
> expressiveness with XPath is a loosing battle.

I don't think that anyone has requested much beyond making the existing API actually usable (either by fixing it directly or by adding a new, simple one). That's all that's needed IMHO and it doesn't strike me as much.

I would be thinking about something along the lines of (untested, off the top of my head):

Node.prototype.queryXPath = function (xpath, ns) {
    ns = ns || {};
    var snap = this.ownerDocument
                   .evaluate(xpath,
                             this,
                             function (p) { return ns[p] || null; },
                             XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                             null);
    var ret = [];
    for (var i = 0; i < snap.snapshotLength; i++) ret.push(snap.snapshotItem(i));
    return ret;
};

or, if people prefer, even just:

Node.prototype.queryXPath = function (xpath) {
    var snap = this.ownerDocument
                   .evaluate(xpath,
                             this,
                             function () { return "http://www.w3.org/1999/xhtml"; },
                             XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                             null);
    var ret = [];
    for (var i = 0; i < snap.snapshotLength; i++) ret.push(snap.snapshotItem(i));
    return ret;
};

Which hardly strikes me as a terribly complex addition.

-- 
Robin Berjon - http://berjon.com/ - @robinberjon
Received on Wednesday, 23 November 2011 10:24:27 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:49 GMT