XPath関数
2009/09/22(火) 10:40 Javascript親記事へこのエントリーをはてなブックマークに追加

$X関数を並べてみる

Nov 17 2007 :: New version of $X / nulog, NULL::something : out of the washer
http://lowreal.net/blog/2007/11/17/1

型指定、複数/単数 タイプで決めていく
// $X(exp);
// $X(exp, context);
// $X(exp, type);
// $X(exp, context, type);
function $X (exp, context, type /* want type */) {
    if (typeof context == "function") {
        type    = context;
        context = null;
    }
    if (!context) context = document;
    var exp = (context.ownerDocument || context).createExpression(exp, function (prefix) {
        var o = document.createNSResolver(context).lookupNamespaceURI(prefix);
        if (o) return o;
        return (document.contentType == "application/xhtml+xml") ? "http://www.w3.org/1999/xhtml" : "";
    });

    switch (type) {
        case String:
            return exp.evaluate(
                context,
                XPathResult.STRING_TYPE,
                null
            ).stringValue;
        case Number:
            return exp.evaluate(
                context,
                XPathResult.NUMBER_TYPE,
                null
            ).numberValue;
        case Boolean:
            return exp.evaluate(
                context,
                XPathResult.BOOLEAN_TYPE,
                null
            ).booleanValue;
        case Array:
            var result = exp.evaluate(
                context,
                XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                null
            );
            var ret = [];
            for (var i = 0, len = result.snapshotLength; i < len; i++) {
                ret.push(result.snapshotItem(i));
            }
            return ret;
        case undefined:
            var result = exp.evaluate(context, XPathResult.ANY_TYPE, null);
            switch (result.resultType) {
                case XPathResult.STRING_TYPE : return result.stringValue;
                case XPathResult.NUMBER_TYPE : return result.numberValue;
                case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
                case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: {
                    // not ensure the order.
                    var ret = [];
                    var i = null;
                    while (i = result.iterateNext()) {
                        ret.push(i);
                    }
                    return ret;
                }
            }
            return null;
        default:
            throw(TypeError("$X: specified type is not valid type."));
    }
}

[javascript]$X関数に少し手を加えてみた
http://d.hatena.ne.jp/ofk/20080204/1202084410
singleNodeValueが拾える
function $X(exp, context, type) {
	if (typeof context == 'function' || typeof context == 'number') {
		type = context;
		context = document;
	}
	else {
		context = context || document;
	}
	exp = (context.ownerDocument || context).createExpression(exp, function (prefix) {
		var o = document.createNSResolver(context).lookupNamespaceURI(prefix);
		return o ? o : (document.contentType == 'application/xhtml+xml') ? 'http://www.w3.org/1999/xhtml' : '';
	});
	if (typeof type == 'number') {
		if (type == 0) {
			return exp.evaluate(context, 9, null).singleNodeValue;
		}
		var result = exp.evaluate(context, 7, null);
		var length = result.snapshotLength;
		if (type < 0) {
			type += length;
		}
		return 0 <= type && type < length ? result.snapshotItem(type) : null;
	}
	switch (type) {
	case Number:
		return exp.evaluate(context, 1, null).numberValue;
	case String:
		return exp.evaluate(context, 2, null).stringValue;
	case Boolean:
		return exp.evaluate(context, 3, null).booleanValue;
	case Array:
		var result = exp.evaluate(context, 7, null), res = [];
		for (var i = 0, j = result.snapshotLength; i < j; ++i) {
			res[res.length] = result.snapshotItem(i);
		}
		return res;
	default:
		var result = exp.evaluate(context, 0, null);
		switch (result.resultType) {
		case 1:
			return result.numberValue;
		case 2:
			return result.stringValue;
		case 3:
			return result.booleanValue;
		case 4:
			var res = [], i = null;
			while (i = result.iterateNext()) {
				res[res.length] = i;
			}
			return res;
		}
		return null;
	}
}

シンプルな$X関数(simple dollar X) - 0xFF
http://d.hatena.ne.jp/os0x/20080730/1217395310

シンプル化
function $X (exp, context) {
	context || (context = document);
	var expr = (context.ownerDocument || context).createExpression(exp, function (prefix) {
	return document.createNSResolver(context.documentElement || context).lookupNamespaceURI(prefix) ||
	context.namespaceURI || document.documentElement.namespaceURI || "";
	});
	 
	var result = expr.evaluate(context, XPathResult.ANY_TYPE, null);
	switch (result.resultType) {
	case XPathResult.STRING_TYPE : return result.stringValue;
	case XPathResult.NUMBER_TYPE : return result.numberValue;
	case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
	case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
	// not ensure the order.
	var ret = [], i = null;
	while (i = result.iterateNext()) ret.push(i);
	return ret;
	}
	return null;
}
XPathEvaluator - 素人がプログラミングを勉強するブログ
http://d.hatena.ne.jp/javascripter/20090225/1235566024

has:真偽値
first:最初
last:最後
all:配列
XPath.reset();してから使用。
var XPath = {
	cache: null,
	reset: function () {
		this.cache = {__proto__: null};
	},
	get: function (context, expr, type) {
		var x = new XPathEvaluator();
		var cache = this.cache, evaluator;
		if (expr in cache) {
			evaluator = cache[expr];
		} else {
			evaluator = cache[expr] = x.createExpression(expr, null);
		}
		return evaluator.evaluate(context, type, null);
	},
	has: function (context, expr) {
		return this.get(context, expr, XPathResult.BOOLEAN_TYPE).booleanValue;
	},
	first: function (context, expr) {
		return this.get(context, expr, XPathResult.FIRST_ORDERED_NODE_TYPE).singleNodeValue;
	},
	last: function (context, expr) {
		var all = this.get(context, expr, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
		return all.snapshotItem(all.snapshotLength - 1) || null;
	},
	all: function (context, expr) {
		var all = this.get(context, expr, XPathResult.ORDERED_NODE_ITERAATE_TYPE);
		var ret = [];
		for (var i; (i = all.iterateNext()) !== null;) {
			ret.push(i);
		}
		return ret;
	}
};
XPath.reset();

名前:  非公開コメント   

  • TB-URL  http://efcl.info/adiary/012/tb/