robotframework-jsonlibrary icon indicating copy to clipboard operation
robotframework-jsonlibrary copied to clipboard

JSONPath $..book[(@.length-1)] fails - Parse error at 1:8 near token ( (()

Open Tset-Noitamotua opened this issue 8 years ago • 3 comments

PREREQUISITE: You have installed JSONLibrary -- > pip install robotframework-jsonlibrary

How to reproduce

  1. create file bookstore.robot with 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}

  1. create file bookstore.json with 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
    }
  }
}

  1. 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))

Tset-Noitamotua avatar Oct 08 '17 12:10 Tset-Noitamotua

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

Tset-Noitamotua avatar Oct 08 '17 12:10 Tset-Noitamotua

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"
                ]
             }
          }
       }
    } 


maqsshah avatar Jul 21 '21 19:07 maqsshah

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).

elrandira avatar May 11 '22 08:05 elrandira