Skip to content

Commit a2ee357

Browse files
committed
Cmp JSONPath
1 parent 7ec0556 commit a2ee357

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

jsonpath_rw/jsonpath.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import unicode_literals, print_function, absolute_import, division, generators, nested_scopes
22
import logging
3+
from operator import gt
34
import six
45
from six.moves import xrange
56
from itertools import *
@@ -565,3 +566,40 @@ def __repr__(self):
565566

566567
def __eq__(self, other):
567568
return isinstance(other, Slice) and other.start == self.start and self.end == other.end and other.step == self.step
569+
570+
571+
class Cmp(JSONPath):
572+
"""
573+
A JSONPath expression that supports value comparison
574+
575+
>>> jsonpath_expr = Cmp(Child(Slice(), Fields('spam')), gt, 2) # "[*].spam gt 2"
576+
>>> matches = jsonpath_expr.find([
577+
... {"spam": 2, "bacon": 1, "sausage": 1},
578+
... {"spam": 10, "baked beans": 1}
579+
... ])
580+
>>> [match.value for match in matches]
581+
[10]
582+
583+
"""
584+
def __init__(self, jsonpath, operator, operand):
585+
if not hasattr(operator, '__call__'):
586+
raise ValueError('operator must be callable')
587+
self.jsonpath = jsonpath
588+
self.op = operator
589+
self.operand = operand
590+
591+
def find(self, data):
592+
return [match for match in self.jsonpath.find(data) if self.op(match.value, self.operand)]
593+
594+
def __str__(self):
595+
return '{jsonpath} {op} {operand}'.format(
596+
jsonpath=self.jsonpath, op=self.op.__name__, operand=repr(self.operand)
597+
)
598+
599+
def __eq__(self, other):
600+
return (
601+
isinstance(other, Cmp) and
602+
other.jsonpath == self.jsonpath and
603+
other.op == self.op and
604+
other.operand == self.operand
605+
)

0 commit comments

Comments
 (0)