h2non / jsonpath-ng

Finally, a JSONPath implementation for Python that aims to be standard compliant. That's all. Enjoy!
Apache License 2.0
582 stars 85 forks source link

(string) key values that contain digits parser error - Exception: Parse error at 1:19 near token 41 (NUMBER) #38

Open clach04 opened 4 years ago

clach04 commented 4 years ago

Test script:

import jsonpath_ng

tmp_data = {
    "Something":
        [
            {
            "Else":
                {
                "41":
                    {
                        "URL": "http://google.com"
                    }
                }
            }
        ]
}

jsonpath_expr = jsonpath_ng.parse('$..URL')
#import pdb ; pdb.set_trace()
for match in jsonpath_expr.find(tmp_data):
    print('%s %s %s'% (match.full_path, match.path, match.value))

match_str = str(match.full_path)
print(match_str)  # expecting: Something.[0].Else.41.URL

jsonpath_expr = jsonpath_ng.parse('Something.[0].Else.*.URL')
for match in jsonpath_expr.find(tmp_data):
    print('%s %s %s'% (match.full_path, match.path, match.value))

jsonpath_expr = jsonpath_ng.parse('Something.[0].Else.41.URL')  # Exception: Parse error at 1:19 near token 41 (NUMBER)
for match in jsonpath_expr.find(tmp_data):
    print('%s %s %s'% (match.full_path, match.path, match.value))

Fails with:

(py3jsonpath) C:\code\py\jsonpath_demo>python update_problem.py
Something.[0].Else.41.URL URL http://google.com
Something.[0].Else.41.URL
Something.[0].Else.41.URL URL http://google.com
Traceback (most recent call last):
  File "update_problem.py", line 31, in <module>
    jsonpath_expr = jsonpath_ng.parse('Something.[0].Else.41.URL')  # Exception: Parse error at 1:19 near token 41 (NUMBER)
  File "C:\code\py\jsonpath_demo\py3jsonpath\lib\site-packages\jsonpath_ng\parser.py", line 14, in parse
    return JsonPathParser().parse(string)
  File "C:\code\py\jsonpath_demo\py3jsonpath\lib\site-packages\jsonpath_ng\parser.py", line 32, in parse
    return self.parse_token_stream(lexer.tokenize(string))
  File "C:\code\py\jsonpath_demo\py3jsonpath\lib\site-packages\jsonpath_ng\parser.py", line 55, in parse_token_stream
    return new_parser.parse(lexer = IteratorToTokenStream(token_iterator))
  File "C:\code\py\jsonpath_demo\py3jsonpath\lib\site-packages\ply\yacc.py", line 333, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
  File "C:\code\py\jsonpath_demo\py3jsonpath\lib\site-packages\ply\yacc.py", line 1201, in parseopt_notrack
    tok = call_errorfunc(self.errorfunc, errtoken, self)
  File "C:\code\py\jsonpath_demo\py3jsonpath\lib\site-packages\ply\yacc.py", line 192, in call_errorfunc
    r = errorfunc(token)
  File "C:\code\py\jsonpath_demo\py3jsonpath\lib\site-packages\jsonpath_ng\parser.py", line 69, in p_error
    raise Exception('Parse error at %s:%s near token %s (%s)' % (t.lineno, t.col, t.value, t.type))
Exception: Parse error at 1:19 near token 41 (NUMBER)
undera commented 4 years ago

Also happens for me with valid UUIDs as keys, for example $.BatchItem.458fee10-643b-11ea-b63e-ebeb7091f738.Events. Online evaluator like this one works fine with it: https://jsonpath.com/

asimell commented 2 years ago

Debugging a bit, I found that parsing the following JSON

{
    "a" : {
        "1": "one",
        "2": "two",
        "3": "three"
    }
}

Using $.a['1'] works, but using $.a.1 does not. I tested this with jsonpath_ng.parse and jsonpath_ng.ext.parse both giving the same result with Python 3.6 and 3.8.