Coder Social home page Coder Social logo

jmespath.js's Introduction

JMESPath

JMESPath (pronounced "james path") allows you to declaratively specify how to extract elements from a JSON document.

For example, given this document:

{"foo": {"bar": "baz"}}

The jmespath expression foo.bar will return "baz".

JMESPath also supports:

Referencing elements in a list. Given the data:

{"foo": {"bar": ["one", "two"]}}

The expression: foo.bar[0] will return "one". You can also reference all the items in a list using the * syntax:

{"foo": {"bar": [{"name": "one"}, {"name": "two"}]}}

The expression: foo.bar[*].name will return ["one", "two"]. Negative indexing is also supported (-1 refers to the last element in the list). Given the data above, the expression foo.bar[-1].name will return "two".

The * can also be used for hash types:

{"foo": {"bar": {"name": "one"}, "baz": {"name": "two"}}}

The expression: foo.*.name will return ["one", "two"].

Installation

You can install JMESPath from pypi with:

pip install jmespath

API

The jmespath.py library has two functions that operate on python data structures. You can use search and give it the jmespath expression and the data:

>>> import jmespath
>>> path = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
'baz'

Similar to the re module, you can use the compile function to compile the JMESPath expression and use this parsed expression to perform repeated searches:

>>> import jmespath
>>> expression = jmespath.compile('foo.bar')
>>> expression.search({'foo': {'bar': 'baz'}})
'baz'
>>> expression.search({'foo': {'bar': 'other'}})
'other'

This is useful if you're going to use the same jmespath expression to search multiple documents. This avoids having to reparse the JMESPath expression each time you search a new document.

Options

You can provide an instance of jmespath.Options to control how a JMESPath expression is evaluated. The most common scenario for using an Options instance is if you want to have ordered output of your dict keys. To do this you can use either of these options:

>>> import jmespath
>>> jmespath.search('{a: a, b: b}',
...                 mydata,
...                 jmespath.Options(dict_cls=collections.OrderedDict))


>>> import jmespath
>>> parsed = jmespath.compile('{a: a, b: b}')
>>> parsed.search(mydata,
...               jmespath.Options(dict_cls=collections.OrderedDict))

Custom Functions

The JMESPath language has numerous built-in functions, but it is also possible to add your own custom functions. Keep in mind that custom function support in jmespath.py is experimental and the API may change based on feedback.

If you have a custom function that you've found useful, consider submitting it to jmespath.site and propose that it be added to the JMESPath language. You can submit proposals here.

To create custom functions:

  • Create a subclass of jmespath.functions.Functions.
  • Create a method with the name _func_<your function name>.
  • Apply the jmespath.functions.signature decorator that indicates the expected types of the function arguments.
  • Provide an instance of your subclass in a jmespath.Options object.

Below are a few examples:

import jmespath
from jmespath import functions

# 1. Create a subclass of functions.Functions.
#    The function.Functions base class has logic
#    that introspects all of its methods and automatically
#    registers your custom functions in its function table.
class CustomFunctions(functions.Functions):

    # 2 and 3.  Create a function that starts with _func_
    # and decorate it with @signature which indicates its
    # expected types.
    # In this example, we're creating a jmespath function
    # called "unique_letters" that accepts a single argument
    # with an expected type "string".
    @functions.signature({'types': ['string']})
    def _func_unique_letters(self, s):
        # Given a string s, return a sorted
        # string of unique letters: 'ccbbadd' ->  'abcd'
        return ''.join(sorted(set(s)))

    # Here's another example.  This is creating
    # a jmespath function called "my_add" that expects
    # two arguments, both of which should be of type number.
    @functions.signature({'types': ['number']}, {'types': ['number']})
    def _func_my_add(self, x, y):
        return x + y

# 4. Provide an instance of your subclass in a Options object.
options = jmespath.Options(custom_functions=CustomFunctions())

# Provide this value to jmespath.search:
# This will print 3
print(
    jmespath.search(
        'my_add(`1`, `2`)', {}, options=options)
)

# This will print "abcd"
print(
    jmespath.search(
        'foo.bar | unique_letters(@)',
        {'foo': {'bar': 'ccbbadd'}},
        options=options)
)

Again, if you come up with useful functions that you think make sense in the JMESPath language (and make sense to implement in all JMESPath libraries, not just python), please let us know at jmespath.site.

Specification

If you'd like to learn more about the JMESPath language, you can check out the JMESPath tutorial. Also check out the JMESPath examples page for examples of more complex jmespath queries.

The grammar is specified using ABNF, as described in RFC4234. You can find the most up to date grammar for JMESPath here.

You can read the full JMESPath specification here.

Testing

In addition to the unit tests for the jmespath modules, there is a tests/compliance directory that contains .json files with test cases. This allows other implementations to verify they are producing the correct output. Each json file is grouped by feature.

Discuss

Join us on our Gitter channel if you want to chat or if you have any questions.

jmespath.js's People

Contributors

basarat avatar g-rath avatar jamesls avatar jeskew avatar liujoycec avatar soxbox avatar timbru31 avatar zommerfelds avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jmespath.js's Issues

Recursive traversal missing

First of all thank you very much for this great library which helped us with our project a lot!!!

Only feature that we really miss is that JMESPath doesn't have recursive traversal. Like the standard feature // in XPath or .. in JsonPath.

Thank you very much for your response

Support custom functions

Is there a timeframe for support for adding our own custom functions - as is already available in jmespath.py?

If this isn't in the pipeline, would you be willing to take a PR for adding this? I'd propose an interface as close as possible to the one already available in Python. So...

> jmespath.search(query, data, { customFunctions : new MyCustomFunctions() })

How JMESPath group by and summary data

How JMESPath group by and summary data

input data :

[
	{
		"value" : 15,
		"name" : "app1"
	},
	{
		"value" : 25,
		"name" : "app1"
	},
	{
		"value" : 30,
		"name" : "app2"
	},
	{
		"value" : 45,
		"name" : "app2"
	}	
]

expected result :

[
	{
		"name" : "app1",
		"summary_value" : 40
	},
	{
		"name" : "app2",
		"summary_value" : 75
	},	
]

what I've tried & thought :
It tried to below code but it not work and return Script error. message

const testData =
[
	{
		"value" : 15,
		"name" : "app1"
	},
	{
		"value" : 25,
		"name" : "app1"
	},
	{
		"value" : 30,
		"name" : "app2"
	},
	{
		"value" : 45,
		"name" : "app2"
	}	
];


console.log( jmespath.search(testData, '[].{name:name,summary_value:sum([?name = name].value)}') );

Demo - JSFiddle - Code Playground

PS : my env is ubuntu and support bash

Ordering operators aren't limited to numbers

Per documentation:

Ordering operators >, >=, <, <= are only valid for numbers. Evaluating any other type with a comparison operator will yield a null value

But this library seems to follow native JavaScript rules instead, allowing e.g. strings to be used in comparisons with non-null results: https://runkit.com/embed/6yymqriowri5

{actual: true, expected: true, expression: "`0` < `1`", scenario: "number ordering_comparator number"}
{actual: true, expected: null, expression: "`0` < '1'", scenario: "number ordering_comparator string"}
{actual: true, expected: null, expression: "'a' < 'b'", scenario: "string ordering_comparator string"}

Feature Request: MongoDB support.

I think jmespath looks like an awesome alternative for the native query language for MongoDB and was wondering about implementing jmespath inside MongoDB (either overriding the existing query, or adding a script) that would allow for jmespath to work on the db level.

Has any one considered this? I'm not 100% sure its possible but it seems so.

This would likely be in another repository (not jmespath.js) but I'd like to start the conversation here.

Typecasting null value to be accepted inside join

Hi, I am processing a json which have array of object inside array of object with possibility of not having required key (or maybe null). and i want to perform join operation on result.

Data I have is as follows
[{"id":3455,"items":[{"id":44099},{"id":6548},{"id":""},{"id":null},{}]},{"id":765765,"items":[]},{"id":2364576,"items":null},{"id":873254}]

Expected Result
[{"id":3455,"itemsid":"44099, 6548"},{"id":765765,"itemsid":""},{"id":2364576,"itemsid":""},{"id":873254,"itemsid":""}]

The query I tried works for positive case but failes in case where expected value not exist.
[].{"id":id,"itemsid": items[].to_string(id) | join(', ', @)}

can someone please help here?

Thanks in advance.

Reduce minified size

I'd like to reduce the minified size of jmespath.js.

I have these constraints:

  • I'd like to stay within a < 5% reduction in performance (via node perf.js), though I could live with up to 10% slower. That is, the performance reduction as a result of changing the unminified jmespath.js should be less than 5%.
  • Must pass all the existing mocha tests. I don't want to modify any of the existing tests. Otherwise this would indicate a change in functionality which I don't want.

An easy test for me:

run-minification jmespath.js > artifacts/jmespath.min.js
cp artifacts/jmespath.min.js jmespath.js
#1. compare performance
$ node perf.js
#2. Run tests and verify they pass
$ mocha

cc @xibz

failed when the field key with dot

var jmespath = require('jmespath');
const data = {
  foo: {'bar.baff': {baz: [0, 1, 2, 3, 4]}},
  b: 2323
}
const result = jmespath.search(data, 'foo["bar.baff"]');
console.log(result);

show errors:

/node_modules/[email protected]@jmespath/jmespath.js:705
              throw error;
              ^

ParserError: Expected Star, got: QuotedIdentifier
    at Parser._match (/Users/hufanee/Github/purejs/node_modules/[email protected]@jmespath/jmespath.js:703:27)
    at Parser.led (/Users/hufanee/Github/purejs/node_modules/[email protected]@jmespath/jmespath.js:687:22)
    at Parser.expression (/Users/hufanee/Github/purejs/node_modules/[email protected]@jmespath/jmespath.js:523:27)
    at Parser.parse (/Users/hufanee/Github/purejs/node_modules/[email protected]@jmespath/jmespath.js:498:26)
    at Object.search (/Users/hufanee/Github/purejs/node_modules/[email protected]@jmespath/jmespath.js:1659:25)
    at Object.<anonymous> (/Users/hufanee/Github/purejs/tempCodeRunnerFile.js:6:25)
    at Module._compile (module.js:649:30)
    at Object.Module._extensions..js (module.js:660:10)
    at Module.load (module.js:561:32)
    at tryModuleLoad (module.js:501:12)

Feature request: access parent object

As a user, I want to use pipe or a modifier or a function to access the parent object.

reservations[].instances[].[tags[?Key=='Name'].Values[] | [0], type, state.name] | [..]

or

reservations[].instances[].[tags[?Key=='Name'].Values[] | [0], type, state.name] | parent(@)

Difference between specification and js implementation

As per the grammar definiton and the example in http://jmespath.org/specification.html#id10 we supposedly can use at least or-expressions in filters ( called bracket-specifier in the grammar )

Additionally the and-expression does not seem to be allowed in the grammar even though the same example uses it ( and it would seem logical )

As far as I can tell the js implementation as of now does not support this, however I did not find any mention of it, and as such spent quite some time thinking I was getting the syntax wrong in my querys.

This is an example session I ran in the chrome console:

jmespath.search({"foo": [{"a": 1, "b": 2}, {"a": 1, "b": 3}]}, "foo[?a==`1`]")
[Object, Object]

jmespath.search({"foo": [{"a": 1, "b": 2}, {"a": 1, "b": 3}]}, "foo[?b==`2`]")
[Object]

jmespath.search({"foo": [{"a": 1, "b": 2}, {"a": 1, "b": 3}]}, "foo[?a==`1`||b==`2`]")
[]

Logically the expected result for me should either be both objects or an exception informing me about a syntax error, like when I try using the documented but utterly unimplemented and-expression

jmespath.search({"foo": [{"a": 1, "b": 2}, {"a": 1, "b": 3}]}, "foo[?a==`1`&&b==`2`]")
jmespath.js:497 Uncaught Error {name: "ParserError", stack: (...), message: "Expected Rbracket, got: Expref"}

Escaped values.

Is there a way to escape user provided keys for use in queries?

How to search in this case

json

{
    1: [
        01: {
            content: "this one"
        },
        02: {
            content: "this two"
        }
    ],
    2: [
        01: {
            content: "this three"
        },
        02: {
            content: "this four"
        }
    ]
}

I want to filter contains "two" keyword and want to return this type of result

{
    1: [
        02: {
            content: "this two"
        }
    ]
}

Is this project alive?

Is this project still being actively supported?
I see a lot of open PRs without feedback and a lot of issues that are very stale.

@jeskew, @jamesls I hope you will forgive me for pinging you.

Are you able to do the minimum maintenance (reviewing / merging PRs), are you looking for help in maintaining this, or should we consider forking this library?

Do we have function to reconstruct from parsed object?

While we could parse the expression into object. I wish that we should be able to also reconstruct the object that was parsed back to expression. So I could write editor and perform some editing, or just partially reconstruct the subexpression into string text

Suppose I have expression propertyA.valueA > `10`

var expression0 = "propertyA.valueA > `10`";
var parsed = jmespath.parse(expression0);

parsed.name = parsed.name == "GT" ? "LT" : "GT";

var expression1 = jmespath.reconstruct(parsed); // became "propertyA.valueA < `10`";

var subExpression = jmespath.reconstruct(parsed.children[0]); // get "propertyA.valueA"
parsed.children[0].name = subExpression == "propertyA.valueA" ? "propertyB.valueB" : "propertyA.valueA";

var expression2 = jmespath.reconstruct(parsed); // became "propertyB.valueB < `10`";

Is it already possible? If not I would like to have this be feature request

Parser incorrectly parses incomplete expression

Tested with python and the jp CLI, incomplete expressions should generate an error. Note the delta here:

$ jp --ast 'foo.'
SyntaxError: Expected identifier, lbracket, or lbrace
foo.
    ^
>>> import jmespath
jmespath.exceptions.ParseError: Expecting: ['quoted_identifier', 'unquoted_identifier', 'lbracket', 'lbrace'], got: eof: Parse error at column 8, token "" (EOF), for expression:
"foo.bar."
         ^
>>>

But in javascript:


> var jmespath = require('./jmespath');
undefined
> jmespath.compile('foo.');
{ type: 'Subexpression',
  children: [ { type: 'Field', name: 'foo' }, undefined ] }

Javascript should be raising an error here.

JMESPath cast string to number then filiter by greater than 0 get “Invalid token (Number): ”0“” error message

I want to get pretaxCost > 0 data but i met trouble like below :

image

my JMESPath

[?pretaxCost.to_number(@) > 0]  

demo data :

[
  {
    "pretaxCost": "7.19999999999999962124684594298729134465020251809619367122650146484375E-8",
    "instanceName": "demo202009210002"
  },
  {
    "pretaxCost": "0",
    "instanceName": "demo202009210002"
  },
  {
    "pretaxCost": "0",
    "instanceName": "demo20092701"
  },
  {
    "pretaxCost": "0.2399999999999999911182158029987476766109466552734375",
    "instanceName": "demo965546464"
  },
  {
    "pretaxCost": "0.06278620880000000681331329133172403089702129364013671875",
    "instanceName": "weihanacrdemo"
  },
  {
    "pretaxCost": "2.16000000000000001872295179138061538282045148662291467189788818359375E-7",
    "instanceName": "092d02d45a464c1291715701"
  }
]

system show error message :

jmespath.min.js:2 Uncaught ParserError: Invalid token (Number): "0"

JSFiddle - Code Playground

what I've tried to think :
I think pretaxCost is string type , so I have to cast type to number,so I use to_number function, then using expression > 0 to get my expected result,but it's not work..

and i tried to only select pretaxCost to_number is work like below demo :
JSFiddle - Code Playground

Shouldn't a slice projection be "chainable"?

Slice expressions will do what they say on the tin such that:

search([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "@[0:10:2]")
// OUTPUTS: [1, 3, 5, 7, 9]

However, chaining slices results in some unexpected responses

search([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "@[0:10:2][*]")
// EXPECTED OUTPUT: [1, 3, 5, 7, 9]
// RECEIVED OUTOUT: []

search([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "@[0:10:2] | @[*]")
// EXPECTED OUTPUT: [1, 3, 5, 7, 9]
// RECEIVED OUTOUT: [1, 3, 5, 7, 9] -- fine

search([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "@[0:10:2][0:3]")
// EXPECTED OUTPUT: [1, 3, 5]
// RECEIVED OUTOUT: []

Unable to search output of `get-bucket-policy` for AWS CLI

Hello, I am trying to parse the output of get-bucket-policy on s3api which looks like this:

{
    "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"AWSCloudTrailAclCheck20150319\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"cloudtrail.amazonaws.com\"},\"Action\":\"s3:GetBucketAcl\",\"Resource\":\"arn:aws:s3:::anothersillys3bucketwhichcanbedeletedlater\"},{\"Sid\":\"AWSCloudTrailWrite20150319\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"cloudtrail.amazonaws.com\"},\"Action\":\"s3:PutObject\",\"Resource\":\"arn:aws:s3:::anothersillys3bucketwhichcanbedeletedlater/AWSLogs/1234567/*\",\"Condition\":{\"StringEquals\":{\"s3:x-amz-acl\":\"bucket-owner-full-control\"}}}]}"
}

Unfortunately, the usual filters won't work. Is there a way to parse this mess of stringified JSON automatically?

I have tried
Policy.Version and Policy.\"Version\" both of which fail.

Filters not working intuitively

Maybe it is my misunderstanding, but with this data:

 {
            "a": {
                "b": [{
                    "c": {
                        "d": {
                            "e": "foo"
                        }
                    },
                    "something": "bar"
                }, {
                    "c": {
                        "d": {
                            "e": "miss"
                        }
                    }
                }]
            }
}

With the following query, nothing returns:

a.b[*].c.d[?e == 'foo']

But this does work:

a.b[*].c.d|@[?e == 'foo']

And in JSON Path (JayWay implementation for example):

a.b[*].c.d[?(@.e == "foo")] is the equivalent.

Is this intentional? they seem functionally equivalent but obviously are not. This fails in the playground (JavaScript), but also fails in the Java implementation.

Is this a spec issue? As designed? Common bug in all implementations? Where do we report something like this that seems to be prevalent across all of JMES?

(jmespath/jmespath.test#15)

Filter by numeric property throws error

Using this data as a test:

[
    {
        "id": 3,
        "otherData": "yo wassup"
    },
    {
        "id": 42,
        "otherData": "et cetera"
    }
]

I'm unable to filter a projection by id because '[?id==42]' gives me Uncaught ParserError: Invalid token (Number): "42". Is there a workaround?

Implementation inconsistency

I had a brief moment of confusion this morning when switching from the ruby library to the javascript library; the search method in the ruby version accepts (expression, data) , while the JS version reverses this and takes (data, expression). Looking at the other implementations, it appears that all of the libraries except for this one accept (expression, data).

I'm not sure that making it consistent is worth the backwards incompatibility, but it's worth noting that this inconsistency exists.

Whitespace character handling

There is a discrepancy with how the JS library parses whitespace vs the PHP library.

 $p  = new \JmesPath\Parser();
var_dump($p->parse("[]\r[]"));
array(3) {
  ["type"]=>
  string(10) "projection"
  ["from"]=>
  string(5) "array"
  ["children"]=>
  array(2) {
    [0]=>
    array(2) {
      ["type"]=>
      string(7) "flatten"
      ["children"]=>
      array(1) {
        [0]=>
        array(3) {
          ["type"]=>
          string(10) "projection"
          ["from"]=>
          string(5) "array"
          ["children"]=>
          array(2) {
            [0]=>
            array(2) {
              ["type"]=>
              string(7) "flatten"
              ["children"]=>
              array(1) {
                [0]=>
                array(1) {
                  ["type"]=>
                  string(7) "current"
                }
              }
            }
            [1]=>
            array(1) {
              ["type"]=>
              string(7) "current"
            }
          }
        }
      }
    }
    [1]=>
    array(1) {
      ["type"]=>
      string(7) "current"
    }
  }
}
jmespath.compile("[]\r[]");
jmespath.js:309 Uncaught LexerError: Unknown character:
    at Lexer.tokenize (https://run.plnkr.co/preview/ck3fuluzv0006315wgzsg94tg/jmespath.js:307:31)
    at Parser._loadTokens (https://run.plnkr.co/preview/ck3fuluzv0006315wgzsg94tg/jmespath.js:523:30)
    at Parser.parse (https://run.plnkr.co/preview/ck3fuluzv0006315wgzsg94tg/jmespath.js:508:16)
    at Object.compile (https://run.plnkr.co/preview/ck3fuluzv0006315wgzsg94tg/jmespath.js:1647:22)
    at <anonymous>:1:10

It seems to me 1 of the implementations is wrong, not sure which.

IE errors

Hi,

I've noticed that recently jmespath.js is having issues in IE. In > IE8 I'm getting Invalid calling object:

https://drive.google.com/file/d/0B64TWB9qdiOMZ2RKc2xLa2ItUzg/view?usp=sharing

In IE8 I'm getting doesn't support property or method 'indexOf':

https://drive.google.com/file/d/0B64TWB9qdiOMaUNXMno1Y3hydFE/view?usp=sharing

The first error is related to this line:

https://github.com/jmespath/jmespath.js/blob/master/jmespath.js#L6

I can't see any recent commits where this has been changed...

I decided to try to work around this using lodash + browserify:

https://github.com/edsilv/jmespath.js

I've changed the isArray method to return _.isArray, toString.call to _.toString, and Object.keys to _.keys.

This is now working for my use cases in > IE8. There's still the problem with indexOf in IE8 which could probably be solved with _.indexOf.

I've strayed pretty far off the reservation though in terms of your code style/setup. I've switched to using gulp too which you may not be keen on.

filtering flattened projection does not seem to follow projection rules

Scenario

If we have an object like so:

{
    "persons": [
        {
            "name": "bob",
            "addresses": [
                {
                    "current": true,
                    "address": "132 Main Ave"
                },
                {
                    "current": false,
                    "address": "99 1st St"
                }
            ]
        },
        {
            "name": "linda",
            "addresses": [
                {
                    "current": true,
                    "address": "132 Main Ave"
                },
                {
                    "current": false,
                    "address": "99 1st St"
                }
            ]
        }
    ]
}

and the query:

persons[?name=='bob'].addresses[]

I get the result

[
  {
    "current": true,
    "address": "132 Main Ave"
  },
  {
    "current": false,
    "address": "99 1st St"
  }
]

This seems to line up just fine with the documentation of what a "projection" is in JMES.
It is my understanding that Filter and Flatten are both types of projections. So if I then filter the flattened projection like so

persons[?name=='bob'].addresses[][?current]

I would expect this

[
  {
    "current": true,
    "address": "132 Main Ave"
  }
]

but instead I have to pipe the result to a filter projection in order to get this to work:

persons[?name=='bob'].addresses[] | [?current]

Question / Issue

I would not expect that I have to first use the pipe operator in order to achieve that.
Why is it that the filter is not applied as a projection of each result of the flatten operation? Am I misunderstanding something about what is/is not a projection and how the projection algorithm is supposed to work?

feature request: the "in" operator

Just a suggestion, because I feel the "in" operator would be useful in several contexts.
A possible syntax could be as follows:
locations[?state in ['WA', 'CA', 'NY']].name

However, the filter might be exposed as a simpler function as follows:
locations[?in(state, ['WA', 'CA', 'NY'])].name

Excellent work, though!

Please add math operation

Should allow

number binary + - * /
boolean binary ^
number unary -

and let's it return null for incompatible type

Security : vulnerability on jquery

Version of jquery bellow 3.0.0 are vulnerables to XSS injection.
The index.html does require a lower version of jquery making the module vulnerable.

ID : CVE-2015-9251
CVSS Score : 6.1
Description : jQuery before 3.0.0 is vulnerable to Cross-site Scripting (XSS) attacks when a cross-domain Ajax request is performed without the dataType option, causing text/javascript responses to be executed.
Origin : jmespath dependency

Recursive flatten

Hi,

Is it possible to retrieve a flattened list of nodes recursively for a tree of arbitrary depth? I know that the flatten operator isn't recursive, but is there some other pattern that can be used?

So for this data:

{
  "node": {
     "label": "root node",
     "nodes": [
       {
         "label": "node 1",
         "nodes": [
           {
             "label": "node 1:1"
           },
           {
             "label": "node 1:2"
           }
         ]
       },
       {
         "label": "node 2",
         "nodes": [
           {
             "label": "node 2:1"
           },
           {
             "label": "node 2:2"
           }
         ]
       }
     ] 
   }
}

I could get:

[
  {
    "label": "root node" 
  },
  {
    "label": "node 1" 
  },
  {
    "label": "node 1:1" 
  },
  {
    "label": "node 1:2" 
  },
  {
    "label": "node 2" 
  },
  {
    "label": "node 2:1" 
  },
  {
    "label": "node 2:2" 
  }
]

Feature request: extend built-in functions

Hello.
We need to add some more built-in functions.

One would be the diff between two numbers. Another function would make a number negative. We can contribute with the code ourselves if it is ok.

filter projection applied twice not working

Hi, good job with this library 👍
Here is the filter machines[?name=='a'].state[?a=='0']

and the JSON

{
  "machines": [
    {"name": "a", "state":   [{"a":"running"}, {"a": "0"}]},
    {"name": "b", "state": "stopped"},
    {"name": "b", "state": "running"}
  ]
}

But it does not return anything ! Am i doing something wrong?

Error messages on type mismatches are difficult to interpret

When this library encounters an invalid type, it will print out the numeric value of the type constant rather than a readable type name. For example, the following error was encountered:

 Error: TypeError: length() expected argument 1 to be type 2,3,4 but received type 7 instead.

With a little digging, I was able to find that this meant the argument should have been a string, array, or object and not null, but the message was pretty cryptic at first.

Bug with dashses in unquoted strings

The following query:

data.relationships.flow-actions.data[].id

is invalid syntax according to the specification, because dashes are not allowed in unquoted strings, however this library allows it. I guess we are missing a spec compliance test that asserts there's a parse error. FYI, the PHP implementation is correct, and rejects that input.

The origin of this report is jmespath/jmespath.php#57 (comment).

Special characters in keys not working

Special characters in keys don't work

If I have data like this:

{ 'foo-bar': 'baz' }

And I use the search: 'foo-bar', it gives error.

> jmespath.search({ 'foo-bar': 'baz' }, 'foo-bar')
Thrown:
{ ParserError: Unexpected token type: Number, value: NaN
    at Parser.parse (\node_modules\jmespath\jmespath.js:502:27)
    at Object.search (\node_modules\jmespath\jmespath.js:1660:25) name: 'ParserError' }

Lots of other special characters don't seem to work either: .,/\|{}

Tested on v0.15.0

equality fails with numbers

{
    "foo": [
        {"category": 2}
    ]
}

jmespath.search(obj, "foo[?category==2]");
ParserError: Invalid token (Number): "2"

If I quote the 2 like this:
jmespath.search(obj, "foo[?category=='2']");

Then the category will not be found.

If I quote the category, and also quote the JSON document, then it will be found.

I believe the correct behavior should be that I do not have to change JSON documents to quote numbers.

The system consider path as valid if the closed apostrophe is missing

Javascript JMESPath library can allow write filter expression without closed apostrophe sign.

For example, in expression
a == 'foo d
for json object
{"a": "foo d", "b": "bar"}
the result will be true and expression can valid.

But, if we try apply it expression in Java JMESPath library, it will be thrown exception:
io.burt.jmespath.parser.ParseException: Unable to compile expression "a == 'foo d": syntax error token recognition error at: ''foo d' at position 5, syntax error mismatched input '<EOF>' expecting {'!', '(', '*', '[', '{', '[?', '@', '', RAW_STRING, JSON_CONSTANT, NAME, STRING} at position 11`
In my opinion, it is bug of Javascript JMESPath library parser, because in JMESPath documentation nowhere write about user can missed closed apostrophe sign.

Using versions:
Javascript JMESPath library: 0.15.0
Java JMESPath library: 0.5.0

Does jmespath support "substring" function

hello, i met a problem ,to use different char idx to switch the business. eg

"01234abc" : extract if ab => way to 1
"01234efg" : extract if ef => way to 2
"01234mno" : extract if mn=> way to 3

I browse the official doc and not found any method to support this.

Dose anybody met the same problem and how to resolve it ?

Length throws an error when evaluating a null node

If the expression passed to a length function call resolves to null, an error will be thrown. Normally, evaluating any JMESPath expression will return a result or null, but if that expression calls any functions then it must be wrapped in a try/catch block to be safely evaluated.

This seems to be in compliance with the specification, which states that "Specifying an invalid type for a function argument will result in a JMESPath error." However, this requires callers to know about the content of a given JMESPath expression before evaluating it.

Add `.npmignore`

The following files seem to be redundantly shipped:

node_modules/jmespath/
node_modules/jmespath/.eslintrc
node_modules/jmespath/.npmignore
node_modules/jmespath/.travis.yml
node_modules/jmespath/BASELINE
node_modules/jmespath/Gruntfile.js
node_modules/jmespath/bower.json
node_modules/jmespath/index.html
node_modules/jmespath/james.html
node_modules/jmespath/perf.js
node_modules/jmespath/reservedWords.json
node_modules/jmespath/test/
node_modules/jmespath/test/compliance.js
node_modules/jmespath/test/jmespath.js
node_modules/jmespath/test/compliance/
node_modules/jmespath/test/compliance/basic.json
node_modules/jmespath/test/compliance/boolean.json
node_modules/jmespath/test/compliance/current.json
node_modules/jmespath/test/compliance/escape.json
node_modules/jmespath/test/compliance/filters.json
node_modules/jmespath/test/compliance/functions.json
node_modules/jmespath/test/compliance/identifiers.json
node_modules/jmespath/test/compliance/indices.json
node_modules/jmespath/test/compliance/literal.json
node_modules/jmespath/test/compliance/multiselect.json
node_modules/jmespath/test/compliance/pipe.json
node_modules/jmespath/test/compliance/slice.json
node_modules/jmespath/test/compliance/syntax.json
node_modules/jmespath/test/compliance/unicode.json
node_modules/jmespath/test/compliance/wildcard.json

Please consider excluding them from packaging.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.