robotframework-jsonlibrary
robotframework-jsonlibrary copied to clipboard
JSONPath $..book[(@.length-1)] fails - Parse error at 1:8 near token ( (()
PREREQUISITE:
You have installed JSONLibrary
-- > pip install robotframework-jsonlibrary
How to reproduce
- create file
bookstore.robotwith following content
*** Settings ***
Library JSONLibrary
Suite Setup BEFORE TEST SUITE
*** Test Cases ***
Get the last book in order
Get Value From Json ${bookstore_data} $..book[(@.length-1)]
*** Keywords ***
BEFORE TEST SUITE
${bookstore_data}= Load JSON From File ${CURDIR}/bookstore.json
Set Suite Variable ${bookstore_data}
- create file
bookstore.jsonwith JSON data:
{ "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
}
}
}
- execute the test
robot -d results -L TRACE bookstore.robot
Result
Parse error at 1:8 near token ( (()
14:19:27.818 DEBUG Traceback (most recent call last):
File "c:\python_virtual_envs\api_requests\lib\site-packages\JSONLibrary\JSONLibraryKeywords.py", line 77, in get_value_from_json
json_path_expr = parse(json_path)
File "c:\python_virtual_envs\api_requests\lib\site-packages\jsonpath_rw_ext\parser.py", line 179, in parse
return ExtentedJsonPathParser(debug=debug).parse(path)
File "c:\python_virtual_envs\api_requests\lib\site-packages\jsonpath_rw\parser.py", line 32, in parse
return self.parse_token_stream(lexer.tokenize(string))
File "c:\python_virtual_envs\api_requests\lib\site-packages\jsonpath_rw\parser.py", line 55, in parse_token_stream
return new_parser.parse(lexer = IteratorToTokenStream(token_iterator))
File "c:\python_virtual_envs\api_requests\lib\site-packages\ply\yacc.py", line 331, in parse
return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
File "c:\python_virtual_envs\api_requests\lib\site-packages\ply\yacc.py", line 1199, in parseopt_notrack
tok = call_errorfunc(self.errorfunc, errtoken, self)
File "c:\python_virtual_envs\api_requests\lib\site-packages\ply\yacc.py", line 193, in call_errorfunc
r = errorfunc(token)
File "c:\python_virtual_envs\api_requests\lib\site-packages\jsonpath_rw\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))
Array slice operator solution for the same use case works:
Get the last book in order
# Get Value From Json ${bookstore_data} $..book[(@.length-1)] > broken as shown above
Get Value From Json ${bookstore_data} $..book[-1:] # works
i am having issue Parse error at 1:3 near token ? (?)
i used different online resources to verify jsonpath, so it is fine.
my jsonpath: $.[?(@.bundle_id==10)].oper_status
my json object:
{
"number_of_lag_in_use": 2,
"number_of_aggregators": 2,
"interfaces": {
"Port-channel10": {
"name": "Port-channel10",
"bundle_id": 10,
"protocol": "lacp",
"flags": "SU",
"oper_status": "up",
"members": {
"TenGigabitEthernet1/0/39": {
"interface": "TenGigabitEthernet1/0/39",
"flags": "P",
"bundled": true,
"port_channel": {
"port_channel_member": true,
"port_channel_int": "Port-channel10"
}
},
"TenGigabitEthernet1/0/40": {
"interface": "TenGigabitEthernet1/0/40",
"flags": "P",
"bundled": true,
"port_channel": {
"port_channel_member": true,
"port_channel_int": "Port-channel10"
}
}
},
"port_channel": {
"port_channel_member": true,
"port_channel_member_intfs": [
"TenGigabitEthernet1/0/39",
"TenGigabitEthernet1/0/40"
]
}
},
"Port-channel34": {
"name": "Port-channel34",
"bundle_id": 34,
"protocol": "lacp",
"flags": "SD",
"oper_status": "down",
"members": {
"TenGigabitEthernet1/0/3": {
"interface": "TenGigabitEthernet1/0/3",
"flags": "D",
"bundled": false,
"port_channel": {
"port_channel_member": true,
"port_channel_int": "Port-channel34"
}
}
},
"port_channel": {
"port_channel_member": true,
"port_channel_member_intfs": [
"TenGigabitEthernet1/0/3"
]
}
}
}
}
length is not recognized by the parser as a specific keyword. Currently, it sees it as a key of a dictionary. Moreover, it is not able to distinguish the '-1' after and consider 'length-1' as a dictionary key (or field in the context of the parser).