⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpath.js

📁 ajax patterns 这是关于ajax设计模式方面的原代码
💻 JS
📖 第 1 页 / 共 4 页
字号:
    return '';  } else {    return xmlValue(this.value[0]);  }}NodeSetValue.prototype.booleanValue = function() {  return this.value.length > 0;}NodeSetValue.prototype.numberValue = function() {  return this.stringValue() - 0;}NodeSetValue.prototype.nodeSetValue = function() {  return this.value;};// XPath expressions. They are used as nodes in the parse tree and// possess an evaluate() method to compute an XPath value given an XPath// context. Expressions are returned from the parser. Teh set of// expression classes closely mirrors the set of non terminal symbols// in the grammar. Every non trivial nonterminal symbol has a// corresponding expression class.//// The common expression interface consists of the following methods://// evaluate(context) -- evaluates the expression, returns a value.//// toString() -- returns the XPath text representation of the// expression (defined in xsltdebug.js).//// parseTree(indent) -- returns a parse tree representation of the// expression (defined in xsltdebug.js).function TokenExpr(m) {  this.value = m;}TokenExpr.prototype.evaluate = function() {  return new StringValue(this.value);};function LocationExpr() {  this.absolute = false;  this.steps = [];}LocationExpr.prototype.appendStep = function(s) {  this.steps.push(s);}LocationExpr.prototype.prependStep = function(s) {  var steps0 = this.steps;  this.steps = [ s ];  for (var i = 0; i < steps0.length; ++i) {    this.steps.push(steps0[i]);  }};LocationExpr.prototype.evaluate = function(ctx) {  var start;  if (this.absolute) {    start = ctx.root;  } else {    start = ctx.node;  }  var nodes = [];  xPathStep(nodes, this.steps, 0, start, ctx);  return new NodeSetValue(nodes);};function xPathStep(nodes, steps, step, input, ctx) {  var s = steps[step];  var ctx2 = ctx.clone(input);  var nodelist = s.evaluate(ctx2).nodeSetValue();  for (var i = 0; i < nodelist.length; ++i) {    if (step == steps.length - 1) {      nodes.push(nodelist[i]);    } else {      xPathStep(nodes, steps, step + 1, nodelist[i], ctx);    }  }}function StepExpr(axis, nodetest, predicate) {  this.axis = axis;  this.nodetest = nodetest;  this.predicate = predicate || [];}StepExpr.prototype.appendPredicate = function(p) {  this.predicate.push(p);}StepExpr.prototype.evaluate = function(ctx) {  var input = ctx.node;  var nodelist = [];  // NOTE(mesch): When this was a switch() statement, it didn't work  // in Safari/2.0. Not sure why though; it resulted in the JavaScript  // console output "undefined" (without any line number or so).  if (this.axis ==  xpathAxis.ANCESTOR_OR_SELF) {    nodelist.push(input);    for (var n = input.parentNode; n; n = input.parentNode) {      nodelist.push(n);    }  } else if (this.axis == xpathAxis.ANCESTOR) {    for (var n = input.parentNode; n; n = input.parentNode) {      nodelist.push(n);    }  } else if (this.axis == xpathAxis.ATTRIBUTE) {    copyArray(nodelist, input.attributes);  } else if (this.axis == xpathAxis.CHILD) {    copyArray(nodelist, input.childNodes);  } else if (this.axis == xpathAxis.DESCENDANT_OR_SELF) {    nodelist.push(input);    xpathCollectDescendants(nodelist, input);  } else if (this.axis == xpathAxis.DESCENDANT) {    xpathCollectDescendants(nodelist, input);  } else if (this.axis == xpathAxis.FOLLOWING) {    for (var n = input.parentNode; n; n = n.parentNode) {      for (var nn = n.nextSibling; nn; nn = nn.nextSibling) {        nodelist.push(nn);        xpathCollectDescendants(nodelist, nn);      }    }  } else if (this.axis == xpathAxis.FOLLOWING_SIBLING) {    for (var n = input.nextSibling; n; n = input.nextSibling) {      nodelist.push(n);    }  } else if (this.axis == xpathAxis.NAMESPACE) {    alert('not implemented: axis namespace');  } else if (this.axis == xpathAxis.PARENT) {    if (input.parentNode) {      nodelist.push(input.parentNode);    }  } else if (this.axis == xpathAxis.PRECEDING) {    for (var n = input.parentNode; n; n = n.parentNode) {      for (var nn = n.previousSibling; nn; nn = nn.previousSibling) {        nodelist.push(nn);        xpathCollectDescendantsReverse(nodelist, nn);      }    }  } else if (this.axis == xpathAxis.PRECEDING_SIBLING) {    for (var n = input.previousSibling; n; n = input.previousSibling) {      nodelist.push(n);    }  } else if (this.axis == xpathAxis.SELF) {    nodelist.push(input);  } else {    throw 'ERROR -- NO SUCH AXIS: ' + this.axis;  }  // process node test  var nodelist0 = nodelist;  nodelist = [];  for (var i = 0; i < nodelist0.length; ++i) {    var n = nodelist0[i];    if (this.nodetest.evaluate(ctx.clone(n, i, nodelist0)).booleanValue()) {      nodelist.push(n);    }  }  // process predicates  for (var i = 0; i < this.predicate.length; ++i) {    var nodelist0 = nodelist;    nodelist = [];    for (var ii = 0; ii < nodelist0.length; ++ii) {      var n = nodelist0[ii];      if (this.predicate[i].evaluate(ctx.clone(n, ii, nodelist0)).booleanValue()) {        nodelist.push(n);      }    }  }  return new NodeSetValue(nodelist);};function NodeTestAny() {  this.value = new BooleanValue(true);}NodeTestAny.prototype.evaluate = function(ctx) {  return this.value;};function NodeTestElement() {}NodeTestElement.prototype.evaluate = function(ctx) {  return new BooleanValue(ctx.node.nodeType == DOM_ELEMENT_NODE);}function NodeTestText() {}NodeTestText.prototype.evaluate = function(ctx) {  return new BooleanValue(ctx.node.nodeType == DOM_TEXT_NODE);}function NodeTestComment() {}NodeTestComment.prototype.evaluate = function(ctx) {  return new BooleanValue(ctx.node.nodeType == DOM_COMMENT_NODE);}function NodeTestPI(target) {  this.target = target;}NodeTestPI.prototype.evaluate = function(ctx) {  return new  BooleanValue(ctx.node.nodeType == DOM_PROCESSING_INSTRUCTION_NODE &&               (!this.target || ctx.node.nodeName == this.target));}function NodeTestNC(nsprefix) {  this.regex = new RegExp("^" + nsprefix + ":");  this.nsprefix = nsprefix;}NodeTestNC.prototype.evaluate = function(ctx) {  var n = ctx.node;  return new BooleanValue(this.regex.match(n.nodeName));}function NodeTestName(name) {  this.name = name;}NodeTestName.prototype.evaluate = function(ctx) {  var n = ctx.node;  return new BooleanValue(n.nodeName == this.name);}function PredicateExpr(expr) {  this.expr = expr;}PredicateExpr.prototype.evaluate = function(ctx) {  var v = this.expr.evaluate(ctx);  if (v.type == 'number') {    // NOTE(mesch): Internally, position is represented starting with    // 0, however in XPath position starts with 1. See functions    // position() and last().    return new BooleanValue(ctx.position == v.numberValue() - 1);  } else {    return new BooleanValue(v.booleanValue());  }};function FunctionCallExpr(name) {  this.name = name;  this.args = [];}FunctionCallExpr.prototype.appendArg = function(arg) {  this.args.push(arg);};FunctionCallExpr.prototype.evaluate = function(ctx) {  var fn = '' + this.name.value;  var f = this.xpathfunctions[fn];  if (f) {    return f.call(this, ctx);  } else {    Log.write('XPath NO SUCH FUNCTION ' + fn);    return new BooleanValue(false);  }};FunctionCallExpr.prototype.xpathfunctions = {  'last': function(ctx) {    assert(this.args.length == 0);    // NOTE(mesch): XPath position starts at 1.    return new NumberValue(ctx.nodelist.length);  },  'position': function(ctx) {    assert(this.args.length == 0);    // NOTE(mesch): XPath position starts at 1.    return new NumberValue(ctx.position + 1);  },  'count': function(ctx) {    assert(this.args.length == 1);    var v = this.args[0].evaluate(ctx);    return new NumberValue(v.nodeSetValue().length);  },  'id': function(ctx) {    assert(this.args.length == 1);    var e = this.args.evaluate(ctx);    var ret = [];    var ids;    if (e.type == 'node-set') {      ids = [];      for (var i = 0; i < e.length; ++i) {        var v = xmlValue(e[i]).split(/\s+/);        for (var ii = 0; ii < v.length; ++ii) {          ids.push(v[ii]);        }      }    } else {      ids = e.split(/\s+/);    }    var d = ctx.node.ownerDocument;    for (var i = 0; i < ids.length; ++i) {      var n = d.getElementById(ids[i]);      if (n) {        ret.push(n);      }    }    return new NodeSetValue(ret);  },  'local-name': function(ctx) {    alert('not implmented yet: XPath function local-name()');  },  'namespace-uri': function(ctx) {    alert('not implmented yet: XPath function namespace-uri()');  },  'name': function(ctx) {    assert(this.args.length == 1 || this.args.length == 0);    var n;    if (this.args.length == 0) {      n = [ ctx.node ];    } else {      n = this.args[0].evaluate(ctx).nodeSetValue();    }    if (n.length == 0) {      return new StringValue('');    } else {      return new StringValue(n[0].nodeName);    }  },  'string':  function(ctx) {    assert(this.args.length == 1 || this.args.length == 0);    if (this.args.length == 0) {      return new StringValue(new NodeSetValue([ ctx.node ]).stringValue());    } else {      return new StringValue(this.args[0].evaluate(ctx).stringValue());    }  },  'concat': function(ctx) {    var ret = '';    for (var i = 0; i < this.args.length; ++i) {      ret += this.args[i].evaluate(ctx).stringValue();    }    return new StringValue(ret);  },  'starts-with': function(ctx) {    assert(this.args.length == 2);    var s0 = this.args[0].evaluate(ctx).stringValue();    var s1 = this.args[1].evaluate(ctx).stringValue();    return new BooleanValue(s0.indexOf(s1) == 0);  },  'contains': function(ctx) {    assert(this.args.length == 2);    var s0 = this.args[0].evaluate(ctx).stringValue();    var s1 = this.args[1].evaluate(ctx).stringValue();    return new BooleanValue(s0.indexOf(s1) != -1);  },  'substring-before': function(ctx) {    assert(this.args.length == 2);    var s0 = this.args[0].evaluate(ctx).stringValue();    var s1 = this.args[1].evaluate(ctx).stringValue();    var i = s0.indexOf(s1);    var ret;    if (i == -1) {      ret = '';    } else {      ret = s0.substr(0,i);    }    return new StringValue(ret);  },  'substring-after': function(ctx) {    assert(this.args.length == 2);    var s0 = this.args[0].evaluate(ctx).stringValue();    var s1 = this.args[1].evaluate(ctx).stringValue();    var i = s0.indexOf(s1);    var ret;    if (i == -1) {      ret = '';    } else {      ret = s0.substr(i + s1.length);    }    return new StringValue(ret);  },  'substring': function(ctx) {    // NOTE: XPath defines the position of the first character in a    // string to be 1, in JavaScript this is 0 ([XPATH] Section 4.2).    assert(this.args.length == 2 || this.args.length == 3);    var s0 = this.args[0].evaluate(ctx).stringValue();    var s1 = this.args[1].evaluate(ctx).numberValue();    var ret;    if (this.args.length == 2) {      var i1 = Math.max(0, Math.round(s1) - 1);      ret = s0.substr(i1);    } else {      var s2 = this.args[2].evaluate(ctx).numberValue();      var i0 = Math.round(s1) - 1;      var i1 = Math.max(0, i0);      var i2 = Math.round(s2) - Math.max(0, -i0);      ret = s0.substr(i1, i2);    }    return new StringValue(ret);  },  'string-length': function(ctx) {    var s;    if (this.args.length > 0) {      s = this.args[0].evaluate(ctx).stringValue();    } else {      s = new NodeSetValue([ ctx.node ]).stringValue();    }    return new NumberValue(s.length);  },  'normalize-space': function(ctx) {    var s;    if (this.args.length > 0) {      s = this.args[0].evaluate(ctx).stringValue();    } else {      s = new NodeSetValue([ ctx.node ]).stringValue();    }    s = s.replace(/^\s*/,'').replace(/\s*$/,'').replace(/\s+/g, ' ');    return new StringValue(s);  },  'translate': function(ctx) {    assert(this.args.length == 3);    var s0 = this.args[0].evaluate(ctx).stringValue();    var s1 = this.args[1].evaluate(ctx).stringValue();    var s2 = this.args[2].evaluate(ctx).stringValue();    for (var i = 0; i < s1.length; ++i) {      s0 = s0.replace(new RegExp(s1.charAt(i), 'g'), s2.charAt(i));    }    return new StringValue(s0);  },  'boolean': function(ctx) {    assert(this.args.length == 1);    return new BooleanValue(this.args[0].evaluate(ctx).booleanValue());  },  'not': function(ctx) {    assert(this.args.length == 1);    var ret = !this.args[0].evaluate(ctx).booleanValue();    return new BooleanValue(ret);  },  'true': function(ctx) {    assert(this.args.length == 0);    return new BooleanValue(true);  },  'false': function(ctx) {    assert(this.args.length == 0);    return new BooleanValue(false);  },  'lang': function(ctx) {    assert(this.args.length == 1);    var lang = this.args[0].evaluate(ctx).stringValue();    var xmllang;    var n = ctx.node;    while (n && n != n.parentNode /* just in case ... */) {      xmllang = n.getAttribute('xml:lang');      if (xmllang) {        break;      }      n = n.parentNode;    }    if (!xmllang) {      return new BooleanValue(false);    } else {      var re = new RegExp('^' + lang + '$', 'i');      return new BooleanValue(xmllang.match(re) ||                              xmllang.replace(/_.*$/,'').match(re));    }  },  'number': function(ctx) {    assert(this.args.length == 1 || this.args.length == 0);    if (this.args.length == 1) {      return new NumberValue(this.args[0].evaluate(ctx).numberValue());    } else {      return new NumberValue(new NodeSetValue([ ctx.node ]).numberValue());    }  },  'sum': function(ctx) {    assert(this.args.length == 1);    var n = this.args[0].evaluate(ctx).nodeSetValue();    var sum = 0;    for (var i = 0; i < n.length; ++i) {      sum += xmlValue(n[i]) - 0;    }    return new NumberValue(sum);  },  'floor': function(ctx) {    assert(this.args.length == 1);    var num = this.args[0].evaluate(ctx).numberValue();    return new NumberValue(Math.floor(num));  },  'ceiling': function(ctx) {    assert(this.args.length == 1);    var num = this.args[0].evaluate(ctx).numberValue();    return new NumberValue(Math.ceil(num));  },  'round': function(ctx) {    assert(this.args.length == 1);    var num = this.args[0].evaluate(ctx).numberValue();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -