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

📄 xpath.js

📁 ajax patterns 这是关于ajax设计模式方面的原代码
💻 JS
📖 第 1 页 / 共 4 页
字号:
  }  return c;}// The axes of XPath expressions.var xpathAxis = {  ANCESTOR_OR_SELF: 'ancestor-or-self',  ANCESTOR: 'ancestor',  ATTRIBUTE: 'attribute',  CHILD: 'child',  DESCENDANT_OR_SELF: 'descendant-or-self',  DESCENDANT: 'descendant',  FOLLOWING_SIBLING: 'following-sibling',  FOLLOWING: 'following',  NAMESPACE: 'namespace',  PARENT: 'parent',  PRECEDING_SIBLING: 'preceding-sibling',  PRECEDING: 'preceding',  SELF: 'self'};var xpathAxesRe = [    xpathAxis.ANCESTOR_OR_SELF,    xpathAxis.ANCESTOR,    xpathAxis.ATTRIBUTE,    xpathAxis.CHILD,    xpathAxis.DESCENDANT_OR_SELF,    xpathAxis.DESCENDANT,    xpathAxis.FOLLOWING_SIBLING,    xpathAxis.FOLLOWING,    xpathAxis.NAMESPACE,    xpathAxis.PARENT,    xpathAxis.PRECEDING_SIBLING,    xpathAxis.PRECEDING,    xpathAxis.SELF].join('|');// The tokens of the language. The label property is just used for// generating debug output. The prec property is the precedence used// for shift/reduce resolution. Default precedence is 0 as a lookahead// token and 2 on the stack. TODO(mesch): this is certainly not// necessary and too complicated. Simplify this!// NOTE: tabular formatting is the big exception, but here it should// be OK.var TOK_PIPE =   { label: "|",   prec:   17, re: new RegExp("^\\|") };var TOK_DSLASH = { label: "//",  prec:   19, re: new RegExp("^//")  };var TOK_SLASH =  { label: "/",   prec:   30, re: new RegExp("^/")   };var TOK_AXIS =   { label: "::",  prec:   20, re: new RegExp("^::")  };var TOK_COLON =  { label: ":",   prec: 1000, re: new RegExp("^:")  };var TOK_AXISNAME = { label: "[axis]", re: new RegExp('^(' + xpathAxesRe + ')') };var TOK_PARENO = { label: "(",   prec:   34, re: new RegExp("^\\(") };var TOK_PARENC = { label: ")",               re: new RegExp("^\\)") };var TOK_DDOT =   { label: "..",  prec:   34, re: new RegExp("^\\.\\.") };var TOK_DOT =    { label: ".",   prec:   34, re: new RegExp("^\\.") };var TOK_AT =     { label: "@",   prec:   34, re: new RegExp("^@")   };var TOK_COMMA =  { label: ",",               re: new RegExp("^,") };var TOK_OR =     { label: "or",  prec:   10, re: new RegExp("^or\\b") };var TOK_AND =    { label: "and", prec:   11, re: new RegExp("^and\\b") };var TOK_EQ =     { label: "=",   prec:   12, re: new RegExp("^=")   };var TOK_NEQ =    { label: "!=",  prec:   12, re: new RegExp("^!=")  };var TOK_GE =     { label: ">=",  prec:   13, re: new RegExp("^>=")  };var TOK_GT =     { label: ">",   prec:   13, re: new RegExp("^>")   };var TOK_LE =     { label: "<=",  prec:   13, re: new RegExp("^<=")  };var TOK_LT =     { label: "<",   prec:   13, re: new RegExp("^<")   };var TOK_PLUS =   { label: "+",   prec:   14, re: new RegExp("^\\+"), left: true };var TOK_MINUS =  { label: "-",   prec:   14, re: new RegExp("^\\-"), left: true };var TOK_DIV =    { label: "div", prec:   15, re: new RegExp("^div\\b"), left: true };var TOK_MOD =    { label: "mod", prec:   15, re: new RegExp("^mod\\b"), left: true };var TOK_BRACKO = { label: "[",   prec:   32, re: new RegExp("^\\[") };var TOK_BRACKC = { label: "]",               re: new RegExp("^\\]") };var TOK_DOLLAR = { label: "$",               re: new RegExp("^\\$") };var TOK_NCNAME = { label: "[ncname]", re: new RegExp('^[a-z][-\\w]*','i') };var TOK_ASTERISK = { label: "*", prec: 15, re: new RegExp("^\\*"), left: true };var TOK_LITERALQ = { label: "[litq]", prec: 20, re: new RegExp("^'[^\\']*'") };var TOK_LITERALQQ = {  label: "[litqq]",  prec: 20,  re: new RegExp('^"[^\\"]*"')};var TOK_NUMBER  = {  label: "[number]",  prec: 35,  re: new RegExp('^\\d+(\\.\\d*)?') };var TOK_QNAME = {  label: "[qname]",  re: new RegExp('^([a-z][-\\w]*:)?[a-z][-\\w]*','i')};var TOK_NODEO = {  label: "[nodetest-start]",  re: new RegExp('^(processing-instruction|comment|text|node)\\(')};// The table of the tokens of our grammar, used by the lexer: first// column the tag, second column a regexp to recognize it in the// input, third column the precedence of the token, fourth column a// factory function for the semantic value of the token.//// NOTE: order of this list is important, because the first match// counts. Cf. DDOT and DOT, and AXIS and COLON.var xpathTokenRules = [    TOK_DSLASH,    TOK_SLASH,    TOK_DDOT,    TOK_DOT,    TOK_AXIS,    TOK_COLON,    TOK_AXISNAME,    TOK_NODEO,    TOK_PARENO,    TOK_PARENC,    TOK_BRACKO,    TOK_BRACKC,    TOK_AT,    TOK_COMMA,    TOK_OR,    TOK_AND,    TOK_NEQ,    TOK_EQ,    TOK_GE,    TOK_GT,    TOK_LE,    TOK_LT,    TOK_PLUS,    TOK_MINUS,    TOK_ASTERISK,    TOK_PIPE,    TOK_MOD,    TOK_DIV,    TOK_LITERALQ,    TOK_LITERALQQ,    TOK_NUMBER,    TOK_QNAME,    TOK_NCNAME,    TOK_DOLLAR];// All the nonterminals of the grammar. The nonterminal objects are// identified by object identity; the labels are used in the debug// output only.var XPathLocationPath = { label: "LocationPath" };var XPathRelativeLocationPath = { label: "RelativeLocationPath" };var XPathAbsoluteLocationPath = { label: "AbsoluteLocationPath" };var XPathStep = { label: "Step" };var XPathNodeTest = { label: "NodeTest" };var XPathPredicate = { label: "Predicate" };var XPathLiteral = { label: "Literal" };var XPathExpr = { label: "Expr" };var XPathPrimaryExpr = { label: "PrimaryExpr" };var XPathVariableReference = { label: "Variablereference" };var XPathNumber = { label: "Number" };var XPathFunctionCall = { label: "FunctionCall" };var XPathArgumentRemainder = { label: "ArgumentRemainder" };var XPathPathExpr = { label: "PathExpr" };var XPathUnionExpr = { label: "UnionExpr" };var XPathFilterExpr = { label: "FilterExpr" };var XPathDigits = { label: "Digits" };var xpathNonTerminals = [    XPathLocationPath,    XPathRelativeLocationPath,    XPathAbsoluteLocationPath,    XPathStep,    XPathNodeTest,    XPathPredicate,    XPathLiteral,    XPathExpr,    XPathPrimaryExpr,    XPathVariableReference,    XPathNumber,    XPathFunctionCall,    XPathArgumentRemainder,    XPathPathExpr,    XPathUnionExpr,    XPathFilterExpr,    XPathDigits];// Quantifiers that are used in the productions of the grammar.var Q_01 = { label: "?" };var Q_MM = { label: "*" };var Q_1M = { label: "+" };// Tag for left associativity (right assoc is implied by undefined).var ASSOC_LEFT = true;// The productions of the grammar. Columns of the table://// - target nonterminal,// - pattern,// - precedence,// - semantic value factory//// The semantic value factory is a function that receives parse tree// nodes from the stack frames of the matched symbols as arguments and// returns an a node of the parse tree. The node is stored in the top// stack frame along with the target object of the rule. The node in// the parse tree is an expression object that has an evaluate() method// and thus evaluates XPath expressions.//// The precedence is used to decide between reducing and shifting by// comparing the precendence of the rule that is candidate for// reducing with the precedence of the look ahead token. Precedence of// -1 means that the precedence of the tokens in the pattern is used// instead. TODO: It shouldn't be necessary to explicitly assign// precedences to rules.var xpathGrammarRules =  [   [ XPathLocationPath, [ XPathRelativeLocationPath ], 18,     passExpr ],   [ XPathLocationPath, [ XPathAbsoluteLocationPath ], 18,     passExpr ],   [ XPathAbsoluteLocationPath, [ TOK_SLASH, XPathRelativeLocationPath ], 18,      makeLocationExpr1 ],   [ XPathAbsoluteLocationPath, [ TOK_DSLASH, XPathRelativeLocationPath ], 18,     makeLocationExpr2 ],   [ XPathAbsoluteLocationPath, [ TOK_SLASH ], 0,     makeLocationExpr3 ],   [ XPathAbsoluteLocationPath, [ TOK_DSLASH ], 0,     makeLocationExpr4 ],   [ XPathRelativeLocationPath, [ XPathStep ], 31,     makeLocationExpr5 ],   [ XPathRelativeLocationPath,     [ XPathRelativeLocationPath, TOK_SLASH, XPathStep ], 31,     makeLocationExpr6 ],   [ XPathRelativeLocationPath,     [ XPathRelativeLocationPath, TOK_DSLASH, XPathStep ], 31,     makeLocationExpr7 ],   [ XPathStep, [ TOK_DOT ], 33,     makeStepExpr1 ],   [ XPathStep, [ TOK_DDOT ], 33,     makeStepExpr2 ],   [ XPathStep,     [ TOK_AXISNAME, TOK_AXIS, XPathNodeTest ], 33,     makeStepExpr3 ],   [ XPathStep, [ TOK_AT, XPathNodeTest ], 33,     makeStepExpr4 ],   [ XPathStep, [ XPathNodeTest ], 33,     makeStepExpr5 ],   [ XPathStep, [ XPathStep, XPathPredicate ], 33,     makeStepExpr6 ],   [ XPathNodeTest, [ TOK_ASTERISK ], 33,     makeNodeTestExpr1 ],   [ XPathNodeTest, [ TOK_NCNAME, TOK_COLON, TOK_ASTERISK ], 33,     makeNodeTestExpr2 ],   [ XPathNodeTest, [ TOK_QNAME ], 33,     makeNodeTestExpr3 ],   [ XPathNodeTest, [ TOK_NODEO, TOK_PARENC ], 33,     makeNodeTestExpr4 ],   [ XPathNodeTest, [ TOK_NODEO, XPathLiteral, TOK_PARENC ], 33,     makeNodeTestExpr5 ],   [ XPathPredicate, [ TOK_BRACKO, XPathExpr, TOK_BRACKC ], 33,     makePredicateExpr ],   [ XPathPrimaryExpr, [ XPathVariableReference ], 33,     passExpr ],   [ XPathPrimaryExpr, [ TOK_PARENO, XPathExpr, TOK_PARENC ], 33,     makePrimaryExpr ],   [ XPathPrimaryExpr, [ XPathLiteral ], 30,     passExpr ],   [ XPathPrimaryExpr, [ XPathNumber ], 30,     passExpr ],   [ XPathPrimaryExpr, [ XPathFunctionCall ], 30,     passExpr ],   [ XPathFunctionCall, [ TOK_QNAME, TOK_PARENO, TOK_PARENC ], -1,     makeFunctionCallExpr1 ],   [ XPathFunctionCall,     [ TOK_QNAME, TOK_PARENO, XPathExpr, XPathArgumentRemainder, Q_MM,       TOK_PARENC ], -1,     makeFunctionCallExpr2 ],   [ XPathArgumentRemainder, [ TOK_COMMA, XPathExpr ], -1,     makeArgumentExpr ],   [ XPathUnionExpr, [ XPathPathExpr ], 20,     passExpr ],   [ XPathUnionExpr, [ XPathUnionExpr, TOK_PIPE, XPathPathExpr ], 20,     makeUnionExpr ],   [ XPathPathExpr, [ XPathLocationPath ], 20,      passExpr ],    [ XPathPathExpr, [ XPathFilterExpr ], 19,      passExpr ],    [ XPathPathExpr,      [ XPathFilterExpr, TOK_SLASH, XPathRelativeLocationPath ], 20,     makePathExpr1 ],   [ XPathPathExpr,     [ XPathFilterExpr, TOK_DSLASH, XPathRelativeLocationPath ], 20,     makePathExpr2 ],   [ XPathFilterExpr, [ XPathPrimaryExpr, XPathPredicate, Q_MM ], 20,     makeFilterExpr ],    [ XPathExpr, [ XPathPrimaryExpr ], 16,     passExpr ],   [ XPathExpr, [ XPathUnionExpr ], 16,     passExpr ],   [ XPathExpr, [ TOK_MINUS, XPathExpr ], -1,     makeUnaryMinusExpr ],   [ XPathExpr, [ XPathExpr, TOK_OR, XPathExpr ], -1,     makeBinaryExpr ],   [ XPathExpr, [ XPathExpr, TOK_AND, XPathExpr ], -1,     makeBinaryExpr ],   [ XPathExpr, [ XPathExpr, TOK_EQ, XPathExpr ], -1,     makeBinaryExpr ],   [ XPathExpr, [ XPathExpr, TOK_NEQ, XPathExpr ], -1,     makeBinaryExpr ],   [ XPathExpr, [ XPathExpr, TOK_LT, XPathExpr ], -1,     makeBinaryExpr ],   [ XPathExpr, [ XPathExpr, TOK_LE, XPathExpr ], -1,     makeBinaryExpr ],   [ XPathExpr, [ XPathExpr, TOK_GT, XPathExpr ], -1,     makeBinaryExpr ],   [ XPathExpr, [ XPathExpr, TOK_GE, XPathExpr ], -1,     makeBinaryExpr ],   [ XPathExpr, [ XPathExpr, TOK_PLUS, XPathExpr ], -1,     makeBinaryExpr, ASSOC_LEFT ],   [ XPathExpr, [ XPathExpr, TOK_MINUS, XPathExpr ], -1,     makeBinaryExpr, ASSOC_LEFT ],   [ XPathExpr, [ XPathExpr, TOK_ASTERISK, XPathExpr ], -1,     makeBinaryExpr, ASSOC_LEFT ],   [ XPathExpr, [ XPathExpr, TOK_DIV, XPathExpr ], -1,     makeBinaryExpr, ASSOC_LEFT ],   [ XPathExpr, [ XPathExpr, TOK_MOD, XPathExpr ], -1,     makeBinaryExpr, ASSOC_LEFT ],   [ XPathLiteral, [ TOK_LITERALQ ], -1,     makeLiteralExpr ],   [ XPathLiteral, [ TOK_LITERALQQ ], -1,     makeLiteralExpr ],   [ XPathNumber, [ TOK_NUMBER ], -1,     makeNumberExpr ],   [ XPathVariableReference, [ TOK_DOLLAR, TOK_QNAME ], 200,     makeVariableReference ]   ];// That function computes some optimizations of the above data// structures and will be called right here. It merely takes the// counter variables out of the global scope.var xpathRules = [];function xpathParseInit() {  if (xpathRules.length) {    return;  }  // Some simple optimizations for the xpath expression parser: sort  // grammar rules descending by length, so that the longest match is  // first found.  xpathGrammarRules.sort(function(a,b) {    var la = a[1].length;    var lb = b[1].length;    if (la < lb) {      return 1;    } else if (la > lb) {      return -1;    } else {      return 0;    }  });  var k = 1;  for (var i = 0; i < xpathNonTerminals.length; ++i) {    xpathNonTerminals[i].key = k++;  }  for (i = 0; i < xpathTokenRules.length; ++i) {    xpathTokenRules[i].key = k++;  }  Log.write('XPath parse INIT: ' + k + ' rules');  // Another slight optimization: sort the rules into bins according  // to the last element (observing quantifiers), so we can restrict  // the match against the stack to the subest of rules that match the  // top of the stack.  //  // TODO(mesch): What we actually want is to compute states as in  // bison, so that we don't have to do any explicit and iterated  // match against the stack.  function push_(array, position, element) {    if (!array[position]) {      array[position] = [];    }    array[position].push(element);  }  for (i = 0; i < xpathGrammarRules.length; ++i) {    var rule = xpathGrammarRules[i];    var pattern = rule[1];    for (var j = pattern.length - 1; j >= 0; --j) {      if (pattern[j] == Q_1M) {        push_(xpathRules, pattern[j-1].key, rule);        break;              } else if (pattern[j] == Q_MM || pattern[j] == Q_01) {        push_(xpathRules, pattern[j-1].key, rule);        --j;      } else {        push_(xpathRules, pattern[j].key, rule);        break;      }    }  }  Log.write('XPath parse INIT: ' + xpathRules.length + ' rule bins');    var sum = 0;  mapExec(xpathRules, function(i) {    if (i) {      sum += i.length;    }  });    Log.write('XPath parse INIT: ' + (sum / xpathRules.length) + ' average bin size');}// Local utility functions that are used by the lexer or parser.function xpathCollectDescendants(nodelist, node) {  for (var n = node.firstChild; n; n = n.nextSibling) {    nodelist.push(n);    arguments.callee(nodelist, n);  }}function xpathCollectDescendantsReverse(nodelist, node) {  for (var n = node.lastChild; n; n = n.previousSibling) {    nodelist.push(n);    arguments.callee(nodelist, n);  }}// The entry point for the library: match an expression against a DOM// node. Returns an XPath value.function xpathDomEval(expr, node) {  var expr1 = xpathParse(expr);  var ret = expr1.evaluate(new ExprContext(node));  return ret;}// Utility function to sort a list of nodes. Used by xsltSort() and// nxslSelect().function xpathSort(input, sort) {  if (sort.length == 0) {    return;  }  var sortlist = [];  for (var i = 0; i < input.nodelist.length; ++i) {    var node = input.nodelist[i];    var sortitem = { node: node, key: [] };    var context = input.clone(node, 0, [ node ]);        for (var j = 0; j < sort.length; ++j) {      var s = sort[j];      var value = s.expr.evaluate(context);      var evalue;      if (s.type == 'text') {        evalue = value.stringValue();      } else if (s.type == 'number') {        evalue = value.numberValue();      }      sortitem.key.push({ value: evalue, order: s.order });    }    // Make the sort stable by adding a lowest priority sort by    // id. This is very convenient and furthermore required by the    // spec ([XSLT] - Section 10 Sorting).    sortitem.key.push({ value: i, order: 'ascending' });    sortlist.push(sortitem);  }  sortlist.sort(xpathSortByKey);  var nodes = [];  for (var i = 0; i < sortlist.length; ++i) {    nodes.push(sortlist[i].node);  }  input.nodelist = nodes;  input.setNode(nodes[0], 0);}// Sorts by all order criteria defined. According to the JavaScript// spec ([ECMA] Section 11.8.5), the compare operators compare strings// as strings and numbers as numbers.//// NOTE: In browsers which do not follow the spec, this breaks only in// the case that numbers should be sorted as strings, which is very// uncommon.function xpathSortByKey(v1, v2) {  // NOTE: Sort key vectors of different length never occur in  // xsltSort.  for (var i = 0; i < v1.key.length; ++i) {    var o = v1.key[i].order == 'descending' ? -1 : 1;    if (v1.key[i].value > v2.key[i].value) {      return +1 * o;    } else if (v1.key[i].value < v2.key[i].value) {      return -1 * o;    }  }  return 0;}

⌨️ 快捷键说明

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