XPath helpers $x and $X
|
|
I'd like to push a little for my XPath micro-library
That is, as long as your XPath query returns DOM nodes (as most do). If, however, it returns a string ( Which, in real code, means you can do XPath without cluttering up your code, as easy and readable as, like in my Image title captions script, for instance:
or, in cases like del.icio.us mp3, where we just want to test for the existence of a node (if no script tag that loads playtagger.js already exists, run the rest of the script):
The That's all. This is the full length of the library (I told you it was small -- though the code readability benefit is huge):
All public domain; use, share and spread the word, as much as you like! |
|
|
I use this function:
function $x(x, t, r) {
if (t && t.nodeType)
var h = r, r = t, t = h;
var d = r ? r.ownerDocument || r : r = document, p;
switch (t) {
case 1:
p = 'numberValue';
break;
case 2:
p = 'stringValue';
break;
case 3:
p = 'booleanValue';
break;
case 8: case 9:
p = 'singleNodeValue';
break;
default:
return d.evaluate(x, r, null, t || 6, null);
}
return d.evaluate(x, r, null, t, null)[p];
}
// Optional shortcut functions I like
function $x1(x, r) { return $x(x, 9, r) }
function $xb(x, r) { return $x(x, 3, r) }
$x is a very smart function because of it's relative element capabilities. You can pass my function a relative reference to an element that is in another document (iframe or result of DOMParser) and it will do all the work for you. I also wrote a forEach function that works with both xpath (iterator or snapshot) results and arrays. The function is much more robust than the native forEach.
function forEach(lst, cb) {
if (lst.snapshotItem)
for (var i = 0, len = lst.snapshotLength; i < len; ++i)
cb(lst.snapshotItem(i), i, lst);
else if (lst.iterateNext) {
var item;
while (item = lst.iterateNext())
cb(item, lst);
} else if (typeof lst.length != 'undefined')
for (var i = 0, len = lst.length; i < len; ++i)
cb(lst[i], i, lst);
else
for (var i in lst)
cb(lst[i], i, lst);
}Last Updated 09/19/09
|
|
|
This is a short one I use. I like to keep it all in one function for all types of results.
function xp(exp, t, n) {
var x = document.evaluate(exp||"//body",n||document,null,t||6,null);
if(t && t>-1 && t<10) switch(t) {
case 1: x=x.numberValue; break;
case 2: x=x.stringValue; break;
case 3: x=x.booleanValue; break;
case 8: case 9: x=x.singleNodeValue; break;
default: break;
} return x;
}
|
|
|
The most important thing to fix is to bring down code verbosity so it actually gets at-a-glance readable. All of the above examples constitute improvement towards that end. |
|
|
Only issue I had was with the $x and $X naming.. Makes it really for me to read code.
|