/** * @license * JSONPath 0.8.0 - XPath for JSON * * Copyright (c) 2007 Stefan Goessner (goessner.net) * Licensed under the MIT (MIT-LICENSE.txt) licence. * * @param {Object|Array} obj * @param {String} expr * @param {Object} [arg] * @returns {Array|false} */ 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) { 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; } }
JSONPath | Description |
---|---|
$ |
The root object/element |
@ |
The current object/element |
. |
Child member operator |
.. |
Recursive descendant operator; JSONPath borrows this syntax from E4X |
* |
Wildcard matching all objects/elements regardless their names |
[] |
Subscript operator |
[,] |
Union operator for alternate names or array indices as a set |
[start:end:step] |
Array slice operator borrowed from ES4 / Python |
?() |
Applies a filter (script) expression via static evaluation |
() |
Script expression via static evaluation |
Given this sample data set, see example expressions below:
{ "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } }
Example JSONPath expressions:
JSONPath | Description |
---|---|
$.store.book[*].author |
The authors of all books in the store |
$..author |
All authors |
$.store.* |
All things in store, which are some books and a red bicycle |
$.store..price |
The price of everything in the store |
$..book[2] |
The third book |
$..book[(@.length-1)] |
The last book via script subscript |
$..book[-1:] |
The last book via slice |
$..book[0,1] |
The first two books via subscript union |
$..book[:2] |
The first two books via subscript array slice |
$..book[?(@.isbn)] |
Filter all books with isbn number |
$..book[?(@.price<10)] |
Filter all books cheaper than 10 |
$..book[?(@.price==8.95)] |
Filter all books that cost 8.95 |
$..book[?(@.price<30 && @.category=="fiction")] |
Filter all fiction books cheaper than 30 |
$..* |
All members of JSON structure |
时间: 2024-10-25 08:02:52