jsonpath for js

/**
         * @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;
            }
        }

 

JSONPathDescription
$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:

JSONPathDescription
$.store.book[*].authorThe authors of all books in the store
$..authorAll authors
$.store.*All things in store, which are some books and a red bicycle
$.store..priceThe 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

 

转载于:https://www.cnblogs.com/theroad/p/7275877.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值