-
-
Save konobi/a31dd7ccb19a317073ae to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/json b/json | |
index 5566714..ace5337 100755 | |
--- a/json | |
+++ b/json | |
@@ -31,6 +31,7 @@ function printHelp() { | |
sys.puts(" -H drop any HTTP header block"); | |
sys.puts(" -i output using node's `sys.inspect`"); | |
sys.puts(" -j output using `JSON.stringfy`, i.e. strict JSON"); | |
+ sys.puts(" --jp search using jsonpath"); | |
sys.puts(""); | |
sys.puts("Examples:"); | |
sys.puts(" curl -s http://search.twitter.com/search.json?q=node.js | json"); | |
@@ -56,7 +57,8 @@ function parseArgv(argv) { | |
quiet: false, | |
dropHeaders: false, | |
outputSysInspect: false, | |
- outputJSON: false | |
+ outputJSON: false, | |
+ jp: false, | |
}; | |
// Turn '-iH' into '-i -H'. | |
@@ -93,6 +95,9 @@ function parseArgv(argv) { | |
case "-j": // output with JSON.stringify | |
parsed.outputJSON = true; | |
break; | |
+ case "--jp": // search using jsonpath | |
+ parsed.jp = true; | |
+ break; | |
default: // arguments | |
if (parsed.lookup === null) { | |
parsed.lookup = arg; | |
@@ -178,7 +183,7 @@ function main(argv) { | |
return; | |
} | |
- if (args.lookup) { | |
+ if (!args.jp && args.lookup) { | |
// Parse command line lookup string into separate parts of the lookup. | |
var split = args.lookup.split(/(\.|\[)/); | |
var bits = []; | |
@@ -221,6 +226,8 @@ function main(argv) { | |
} | |
data = Script.runInNewContext("(" + JSON.stringify(data) + ")" + lookup); | |
+ } else if (args.jp && args.lookup) { | |
+ data = jsonPath(data, args.lookup, { resultType: 'VALUE' }); | |
} | |
// Print out results. | |
@@ -247,3 +254,92 @@ if (require.main === module) { | |
process.exit(retval); | |
} | |
} | |
+ | |
+ | |
+/* JSONPath 0.8.0 - XPath for JSON | |
+ * | |
+ * Copyright (c) 2007 Stefan Goessner (goessner.net) | |
+ * Licensed under the MIT (MIT-LICENSE.txt) licence. | |
+ */ | |
+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){return "[#"+(subx.push($1)-1)+"]";}) | |
+ .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)) { // [name1,name2,...] | |
+ for (var s=loc.split(/'?,'?/),i=0,n=s.length; i<n; i++) | |
+ P.trace(s[i]+";"+x, val, path); | |
+ } | |
+ 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[m],m)) P.trace(m+";"+x,v,p); }); | |
+ else if (/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(loc)) // [start:end:step] phyton slice syntax | |
+ P.slice(loc, 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, "_v")); } | |
+ catch(e) { throw new SyntaxError("jsonPath: " + e.message + ": " + x.replace(/@/g, "_v").replace(/\^/g, "_a")); } | |
+ } | |
+ }; | |
+ | |
+ var $ = obj; | |
+ if (expr && obj && (P.resultType == "VALUE" || P.resultType == "PATH")) { | |
+ P.trace(P.normalize(expr).replace(/^\$;/,""), obj, "$"); | |
+ return P.result.length ? P.result : false; | |
+ } | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment