Blame view

datalets/shared_js/jsonpath-0.8.5.js 4.35 KB
73bcce88   luigser   COMPONENTS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  /* JSONPath 0.8.5 - XPath for JSON

   *

   * Copyright (c) 2007 Stefan Goessner (goessner.net)

   * Licensed under the MIT (MIT-LICENSE.txt) licence.

   *

   * Proposal of Chris Zyp goes into version 0.9.x

   * Issue 7 resolved

   */

  function jsonPath(obj, expr, arg) {

      var P = {

          resultType: arg && arg.resultType || "VALUE",

          result: [],

          normalize: function(expr) {

              var subx = [];

              return expr.replace(/[\['](\??\(.*?\))[\]']|\['(.*?)'\]/g, function($0,$1,$2){return "[#"+(subx.push($1||$2)-1)+"]";})  /* http://code.google.com/p/jsonpath/issues/detail?id=4 */

                  .replace(/'?\.'?|\['?/g, ";")

                  .replace(/;;;|;;/g, ";..;")

                  .replace(/;$|'?\]|'$/g, "")

                  .replace(/#([0-9]+)/g, function($0,$1){return subx[$1];});

          },

          asPath: function(path) {

              var x = path.split(";"), p = "$";

              for (var i=1,n=x.length; i<n; i++)

                  p += /^[0-9*]+$/.test(x[i]) ? ("["+x[i]+"]") : ("['"+x[i]+"']");

              return p;

          },

          store: function(p, v) {

              if (p) P.result[P.result.length] = P.resultType == "PATH" ? P.asPath(p) : v;

              return !!p;

          },

          trace: function(expr, val, path) {

              if (expr !== "") {

                  var x = expr.split(";"), loc = x.shift();

                  x = x.join(";");

                  if (val && val.hasOwnProperty(loc))

                      P.trace(x, val[loc], path + ";" + loc);

                  else if (loc === "*")

                      P.walk(loc, x, val, path, function(m,l,x,v,p) { P.trace(m+";"+x,v,p); });

                  else if (loc === "..") {

                      P.trace(x, val, path);

                      P.walk(loc, x, val, path, function(m,l,x,v,p) { typeof v[m] === "object" && P.trace("..;"+x,v[m],p+";"+m); });

                  }

                  else if (/^\(.*?\)$/.test(loc)) // [(expr)]

                      P.trace(P.eval(loc, val, path.substr(path.lastIndexOf(";")+1))+";"+x, val, path);

                  else if (/^\?\(.*?\)$/.test(loc)) // [?(expr)]

                      P.walk(loc, x, val, path, function(m,l,x,v,p) { if (P.eval(l.replace(/^\?\((.*?)\)$/,"$1"), v instanceof Array ? v[m] : v, m)) P.trace(m+";"+x,v,p); }); // issue 5 resolved

                  else if (/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(loc)) // [start:end:step]  phyton slice syntax

                      P.slice(loc, x, val, path);

                  else if (/,/.test(loc)) { // [name1,name2,...]

                      for (var s=loc.split(/'?,'?/),i=0,n=s.length; i<n; i++)

                          P.trace(s[i]+";"+x, val, path);

                  }

              }

              else

                  P.store(path, val);

          },

          walk: function(loc, expr, val, path, f) {

              if (val instanceof Array) {

                  for (var i=0,n=val.length; i<n; i++)

                      if (i in val)

                          f(i,loc,expr,val,path);

              }

              else if (typeof val === "object") {

                  for (var m in val)

                      if (val.hasOwnProperty(m))

                          f(m,loc,expr,val,path);

              }

          },

          slice: function(loc, expr, val, path) {

              if (val instanceof Array) {

                  var len=val.length, start=0, end=len, step=1;

                  loc.replace(/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/g, function($0,$1,$2,$3){start=parseInt($1||start);end=parseInt($2||end);step=parseInt($3||step);});

                  start = (start < 0) ? Math.max(0,start+len) : Math.min(len,start);

                  end   = (end < 0)   ? Math.max(0,end+len)   : Math.min(len,end);

                  for (var i=start; i<end; i+=step)

                      P.trace(i+";"+expr, val, path);

              }

          },

          eval: function(x, _v, _vname) {

              try { return $ && _v && eval(x.replace(/(^|[^\\])@/g, "$1_v").replace(/\\@/g, "@")); }  // issue 7 : resolved ..

              catch(e) { throw new SyntaxError("jsonPath: " + e.message + ": " + x.replace(/(^|[^\\])@/g, "$1_v").replace(/\\@/g, "@")); }  // issue 7 : resolved ..

          }

      };

  

      var $ = obj;

      if (expr && obj && (P.resultType == "VALUE" || P.resultType == "PATH")) {

          P.trace(P.normalize(expr).replace(/^\$;?/,""), obj, "$");  // issue 6 resolved

          return P.result.length ? P.result : false;

      }

  }