JavaScript: $g

var $g = function(xexp, context, type, thisp){
    if (!context) context = document;
    var doc = context.ownerDocument || context, defaultNamespaceURI = (/xml$/).test(doc.contentType) ? doc.documentElement.getAttribute("xmlns") : "";
    var resolver = function(prefix){
        return doc.createNSResolver(context).lookupNamespaceURI(prefix) || defaultNamespaceURI;
    };
    switch (typeof(type)) {
    case "number":
        return doc.evaluate(xexp, context, resolver, XPathResult.NUMBER_TYPE, null).numberValue;
    case "string":
        return doc.evaluate(xexp, context, resolver, XPathResult.STRING_TYPE, null).stringValue;
    case "boolean":
        return doc.evaluate(xexp, context, resolver, XPathResult.BOOLEAN_TYPE, null).booleanValue;
    case "function":
        var ret = [], xp = doc.evaluate(xexp, context, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
        for (var i=0,l=xp.snapshotLength,node; i<l; i++) {
            node = type.apply(thisp, [xp.snapshotItem(i), i, xp]);
            if (typeof(node) !== "undefined") ret.push(node);
        }
        return ret;
    case "object":
        var ret = [], xp = doc.evaluate(xexp, context, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
        for (var i=0,l=xp.snapshotLength,node; i<l; i++) {
            node = xp.snapshotItem(i);
            ret[i] = (node.nodeType === 2) ? (node.nodeName === "href" || node.nodeName === "src") ? node.ownerElement[node.nodeName]
                                                                                                   : node.nodeValue
                                           : node.textContent;
        }
        return ret;
    default:
        var ret = [], xp = doc.evaluate(xexp, context, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
        for (var i=0,l=xp.snapshotLength; i<l; i++) {
            ret[i] = xp.snapshotItem(i);
        }
        return ret;
    }
};
$g('//a')
// -> [a note, ...]

$g('count(//a)', null, 0)
// -> 149

$g('/descendant::a[1]/@href', null, "")
// -> "http://mayokara.info/note/"

$g('//a', null, function(v){return {href: v.href, textContent: v.textContent};})
// -> [Object href=http://mayokara.info/note/, ...]

$g('//a', null, function(v){if (v.href.indexOf("mayokara.info") === -1) return v;})
// -> [a 1214557471, ...]

第3引数のtypeofに応じて挙動を変えるdocument.evaluateラッパー。

1パスでmap/filterできるのが特長。

gはgetのg。

Comment: 0

Comment Form
Name
URL
Comment

Trackback: 0

Trackback URL
http://mayokara.info/note/trackback/231
Attention
スパム対策のため、当エントリへのリンクがないトラックバックをブロックしています。