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

📄 gdata_condensed.js

📁 google gdata API 很好用的API
💻 JS
📖 第 1 页 / 共 5 页
字号:
      return XMLX_parse(xmlNode, xpath);     }  } catch (e) {     // LOG_XML_PRINT(xmlNode);      // this is everyone else    LOG_DEBUG("XML_getNodes:  catch path - " + e.toString());    return XMLX_parse(xmlNode, xpath);   }};/** * helper method to call the javascript parser*/function XMLX_parse(xmlNode, xpath) {  LOG_DEBUG("XML_parse:  no xpath support, hence i am here");   var expr = xpathParse(xpath);  var ctx = new ExprContext(xmlNode);  var ret = expr.evaluate(ctx);  return ret.nodeSetValue();}/*** @param xmlNode the node to search from* @xpath the xpath to search for* @return the first xmlnode found*/function XMLX_getNode(xmlNode, xpath) {  var result = XMLX_getNodes(xmlNode, xpath);  if (result) {    return result[0];   }  return null; }// remove this if you merge if (window.GD_Loader) {  // continue loading  window.GD_Loader();}// end/* Copyright (c) 2006 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */// All Rights Reserved//// An XPath parser and evaluator written in JavaScript. The// implementation is complete except for functions handling// namespaces.//// Reference: [XPATH] XPath Specification// <http://www.w3.org/TR/1999/REC-xpath-19991116>.////// The API of the parser has several parts://// 1. The parser function xpathParse() that takes a string and returns// an expession object.//// 2. The expression object that has an evaluate() method to evaluate the// XPath expression it represents. (It is actually a hierarchy of// objects that resembles the parse tree, but an application will call// evaluate() only on the top node of this hierarchy.)//// 3. The context object that is passed as an argument to the evaluate()// method, which represents the DOM context in which the expression is// evaluated.//// 4. The value object that is returned from evaluate() and represents// values of the different types that are defined by XPath (number,// string, boolean, and node-set), and allows to convert between them.//// These parts are near the top of the file, the functions and data// that are used internally follow after them.//function assert(condition) { DBG_ASSERT(condition); }// The entry point for the parser.//// @param expr a string that contains an XPath expression.// @return an expression object that can be evaluated with an// expression context.// right now, only used for safarifunction xpathParse(expr) {  LOG_DEBUG('XPath parse ' + expr);  xpathParseInit();  var cached = xpathCacheLookup(expr);  if (cached) {    LOG_DEBUG('XPath ....cached ');    return cached;  }  // Optimize for a few common cases: simple attribute node tests  // (@id), simple element node tests (page), variable references  // ($address), numbers (4), multi-step path expressions where each  // step is a plain element node test  // (page/overlay/locations/location).    if (expr.match(/^(\$|@)?\w+$/i)) {    var ret = makeSimpleExpr(expr);    xpathParseCache[expr] = ret;    LOG_DEBUG('XPath ... simple');    return ret;  }  if (expr.match(/^\w+(\/\w+)*$/i)) {    ret = makeSimpleExpr2(expr);    xpathParseCache[expr] = ret;    LOG_DEBUG('XPath ... simple 2 ');    return ret;  }  var cachekey = expr; // expr is modified during parse  var stack = [];  var ahead = null;  var previous = null;  var done = false;  var parse_count = 0;  var lexer_count = 0;  var reduce_count = 0;    while (!done) {    parse_count+=1;    expr = expr.replace(/^\s*/, '');    previous = ahead;    ahead = null;    var rule = null;    var match = '';    for (var i = 0; i < xpathTokenRules.length; ++i) {      var result = xpathTokenRules[i].re.exec(expr);      lexer_count+=1;      if (result && result.length > 0 && result[0].length > match.length) {        rule = xpathTokenRules[i];        match = result[0];        break;      }    }    // Special case: allow operator keywords to be element and    // variable names.    // NOTE: The parser resolves conflicts by looking ahead,    // and this is the only case where we look back to    // disambiguate. So this is indeed something different, and    // looking back is usually done in the lexer (via states in the    // general case, called "start conditions" in flex(1)). Also,the    // conflict resolution in the parser is not as robust as it could    // be, so I'd like to keep as much off the parser as possible (all    // these precedence values should be computed from the grammar    // rules and possibly associativity declarations, as in bison(1),    // and not explicitly set.    if (rule &&        (rule == TOK_DIV ||          rule == TOK_MOD ||         rule == TOK_AND ||          rule == TOK_OR) &&        (!previous ||          previous.tag == TOK_AT ||          previous.tag == TOK_DSLASH ||          previous.tag == TOK_SLASH ||         previous.tag == TOK_AXIS ||          previous.tag == TOK_DOLLAR)) {      rule = TOK_QNAME;    }    if (rule) {      expr = expr.substr(match.length);      LOG_DEBUG('XPath token:  parse ' + match + ' -- ' + rule.label);      ahead = {        tag: rule,        match: match,        prec: rule.prec ?  rule.prec : 0, // || 0 is removed by the compiler        expr: makeTokenExpr(match) };    } else {      LOG_DEBUG('XPath DONE');      done = true;    }    while (xpathReduce(stack, ahead)) {      reduce_count+=1;      LOG_DEBUG('XPATH stack: ' + stackToString(stack));    }  }  LOG_DEBUG('XPATH stack:' + stackToString(stack));  if (stack.length != 1) {    throw 'XPath parse error ' + cachekey + ':\n' + stackToString(stack);  }  result = stack[0].expr;  xpathParseCache[cachekey] = result;  LOG_DEBUG('XPath parse: ' + parse_count + ' / ' +         lexer_count + ' / ' + reduce_count);  return result;}var xpathParseCache = {};function xpathCacheLookup(expr) {  return xpathParseCache[expr];}function xpathReduce(stack, ahead) {  var cand = null;  if (stack.length > 0) {    var top = stack[stack.length-1];    var ruleset = xpathRules[top.tag.key];    if (ruleset) {      for (var i = 0; i < ruleset.length; ++i) {        var rule = ruleset[i];        var match = xpathMatchStack(stack, rule[1]);        if (match.length) {          cand = {            tag: rule[0],            rule: rule,            match: match };          cand.prec = xpathGrammarPrecedence(cand);          break;        }      }    }  }  var ret;  if (cand && (!ahead || cand.prec > ahead.prec ||                (ahead.tag.left && cand.prec >= ahead.prec))) {    for (i = 0; i < cand.match.matchlength; ++i) {      stack.pop();    }    LOG_DEBUG('reduce ' + cand.tag.label + ' ' + cand.prec +          ' ahead ' + (ahead ? ahead.tag.label + ' ' + ahead.prec +                        (ahead.tag.left ? ' left' : '') : ' none '));    var matchexpr = UTIL_mapExpr(cand.match, function(m) { return m.expr; });    cand.expr = cand.rule[3].apply(null, matchexpr);    stack.push(cand);    ret = true;  } else {    if (ahead) {      LOG_DEBUG('shift ' + ahead.tag.label + ' ' + ahead.prec +             (ahead.tag.left ? ' left' : '') +            ' over ' + (cand ? cand.tag.label + ' ' +                         cand.prec : ' none'));      stack.push(ahead);    }    ret = false;  }  return ret;}function xpathMatchStack(stack, pattern) {  // NOTE: The stack matches for variable cardinality are  // greedy but don't do backtracking. This would be an issue only  // with rules of the form A* A, i.e. with an element with variable  // cardinality followed by the same element. Since that doesn't  // occur in the grammar at hand, all matches on the stack are  // unambiguous.  var S = stack.length;  var P = pattern.length;  var p, s;  var match = [];  match.matchlength = 0;  var ds = 0;  for (p = P - 1, s = S - 1; p >= 0 && s >= 0; --p, s -= ds) {    ds = 0;    var qmatch = [];    if (pattern[p] == Q_MM) {      p -= 1;      match.push(qmatch);      while (s - ds >= 0 && stack[s - ds].tag == pattern[p]) {        qmatch.push(stack[s - ds]);        ds += 1;        match.matchlength += 1;      }    } else if (pattern[p] == Q_01) {      p -= 1;      match.push(qmatch);      while (s - ds >= 0 && ds < 2 && stack[s - ds].tag == pattern[p]) {        qmatch.push(stack[s - ds]);        ds += 1;        match.matchlength += 1;      }    } else if (pattern[p] == Q_1M) {      p -= 1;      match.push(qmatch);      if (stack[s].tag == pattern[p]) {        while (s - ds >= 0 && stack[s - ds].tag == pattern[p]) {          qmatch.push(stack[s - ds]);          ds += 1;          match.matchlength += 1;        }      } else {        return [];      }    } else if (stack[s].tag == pattern[p]) {      match.push(stack[s]);      ds += 1;      match.matchlength += 1;    } else {      return [];    }    UTIL_reverseInplace(qmatch);    qmatch.expr = UTIL_mapExpr(qmatch, function(m) { return m.expr; });  }  UTIL_reverseInplace(match);  if (p == -1) {    return match;  } else {    return [];  }}function xpathTokenPrecedence(tag) {  return tag.prec || 2;}function xpathGrammarPrecedence(frame) {  var ret = 0;  if (frame.rule) { /* normal reduce */    if (frame.rule.length >= 3 && frame.rule[2] >= 0) {      ret = frame.rule[2];    } else {      for (var i = 0; i < frame.rule[1].length; ++i) {        var p = xpathTokenPrecedence(frame.rule[1][i]);        ret = Math.max(ret, p);      }    }  } else if (frame.tag) { /* TOKEN match */    ret = xpathTokenPrecedence(frame.tag);  } else if (frame.length) { /* Q_ match */    for (var j = 0; j < frame.length; ++j) {      var p = xpathGrammarPrecedence(frame[j]);      ret = Math.max(ret, p);    }  }  return ret;}function stackToString(stack) {  var ret = '';  for (var i = 0; i < stack.length; ++i) {    if (ret) {      ret += '\n';    }    ret += stack[i].tag.label;  }  return ret;}// XPath expression evaluation context. An XPath context consists of a// DOM node, a list of DOM nodes that contains this node, a number// that represents the position of the single node in the list, and a// current set of variable bindings. (See XPath spec.)//// The interface of the expression context:////   Constructor -- gets the node, its position, the node set it//   belongs to, and a parent context as arguments. The parent context//   is used to implement scoping rules for variables: if a variable//   is not found in the current context, it is looked for in the//   parent context, recursively. Except for node, all arguments have//   default values: default position is 0, default node set is the//   set that contains only the node, and the default parent is null.////     Notice that position starts at 0 at the outside interface;//     inside XPath expressions this shows up as position()=1.////   clone() -- creates a new context with the current context as//   parent. If passed as argument to clone(), the new context has a//   different node, position, or node set. What is not passed is//   inherited from the cloned context.////   setVariable(name, expr) -- binds given XPath expression to the//   name.////   getVariable(name) -- what the name says.////   setNode(node, position) -- sets the context to the new node and//   its corresponding position. Needed to implement scoping rules for//   variables in XPath. (A variable is visible to all subsequent//   siblings, not only to its children.)function ExprContext(node, position, nodelist, parent) {  this.node = node;  this.position = position || 0;  this.nodelist = nodelist || [ node ];  this.variables = {};  this.parent = parent || null;  if (parent) {    this.root = parent.root;  } else if (this.node.nodeType == DOM_DOCUMENT_NODE) {    // NOTE: DOM Spec stipulates that the ownerDocument of a    // document is null. Our root, however is the document that we are    // processing, so the initial context is created from its document    // node, which case we must handle here explcitly.    this.root = node;  } else {    this.root = node.ownerDocument;  }}ExprContext.prototype.clone = function(node, position, nodelist) {  return new ExprContext(      node || this.node,      typeof position != 'undefined' ? position : this.position,      nodelist || this.nodelist, this);};ExprContext.prototype.setVariable = function(name, value) {  this.variables[name] = value;};ExprContext.prototype.getVariable = function(name) {  if (typeof this.variables[name] != 'undefined') {    return this.variables[name];  } else if (this.parent) {    return this.parent.getVariable(name);  } else {    return null;  }}ExprContext.prototype.setNode = function(node, position) {  this.node = node;  this.position = position;}// XPath expression values. They are what XPath expressions evaluate

⌨️ 快捷键说明

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