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