10

Here's my json:

{
   'test': [
        { "id": "1", "description": "Test 1" },
        { "id": "2", "description": "Test 2" }
    ]
}

I'm trying to get the value for id where description is "Test 1".

I found the following example on the JsonPath page:

$..book[?(@.price<10)]

When trying to parse the following jsonxpath expression:

parse('$..test[?(@.description="Test 1")].id')

I get the following error:

jsonpath_rw.lexer.JsonPathLexerError: Error on line 1, col 7: Unexpected character: ?

What am I doing wrong? Alternatively, is there a better way to do this?

Pavel Chernikov
  • 2,186
  • 1
  • 20
  • 37
  • 3
    Oddly enough, looking at the [lexer code](https://github.com/kennknowles/python-jsonpath-rw/blob/master/jsonpath_rw/lexer.py), jsonpath-rw doesn't appear to support the `?(boolean)` filter mechanism at all. – voithos May 24 '15 at 01:13

1 Answers1

10

It appears that jsonpath-rw doesn't support this feature. Perhaps consider another library? ObjectPath looks promising:

>>> import objectpath
>>> json_obj = { ... } # This has to be pre-parsed
>>> tree = objectpath.Tree(json_obj)
>>> ids = tree.execute('$..test[@.description is "Test 1"].id')
>>> print list(ids)
["1"]

It doesn't quite follow the JsonPath syntax exactly, but it's quite similar, at least from a perfunctory survey. Documentation is also available.

Of course, if your JSON will always be in the same form (i.e. you won't have to deal with missing child objects, etc), then you could easily do the same query using a list comprehension, or something similar.

json = { ... }
ids = [t['id'] for t in json['test'] if t['description'] == 'Test 1']
voithos
  • 68,482
  • 12
  • 101
  • 116
  • 2
    Just keep in mind that `..` operator (recursive descent/deep search) is very slow. Use `.` if you are sure that test is in the root of the document and only in the root of the document. – Adrian Kalbarczyk Nov 20 '15 at 12:53