def exitNotExpression(self, ctx:JSONPathParser.NotExpressionContext): if ctx.getToken(JSONPathParser.NOT, 0) is not None: expression = self._stack.pop() if isinstance(expression, NotUnaryOperatorExpression): self._stack.append(expression.expression) else: self._stack.append(NotUnaryOperatorExpression(expression)) elif (ctx.getToken(JSONPathParser.ROOT_VALUE, 0) is not None) or (ctx.getToken(JSONPathParser.CURRENT_VALUE, 0) is not None): if bool(ctx.value()): right_value = self._stack.pop() if bool(ctx.subscript()): next_node = self._stack.pop() else: next_node = TerminalNode() if ctx.getToken(JSONPathParser.ROOT_VALUE, 0) is not None: left_node = RootNode(next_node) elif ctx.getToken(JSONPathParser.CURRENT_VALUE, 0) is not None: left_node = CurrentNode(next_node) else: raise ValueError() if ctx.getToken(JSONPathParser.EQ, 0) is not None: self._stack.append(EqualBinaryOperatorExpression(left_node, right_value)) elif ctx.getToken(JSONPathParser.NE, 0) is not None: self._stack.append(NotEqualBinaryOperatorExpression(left_node, right_value)) elif ctx.getToken(JSONPathParser.LT, 0) is not None: self._stack.append(LessThanBinaryOperatorExpression(left_node, right_value)) elif ctx.getToken(JSONPathParser.LE, 0) is not None: self._stack.append(LessThanOrEqualToBinaryOperatorExpression(left_node, right_value)) elif ctx.getToken(JSONPathParser.GT, 0) is not None: self._stack.append(GreaterThanBinaryOperatorExpression(left_node, right_value)) elif ctx.getToken(JSONPathParser.GE, 0) is not None: self._stack.append(GreaterThanOrEqualToBinaryOperatorExpression(left_node, right_value)) else: raise ValueError() else: if bool(ctx.subscript()): next_node = self._stack.pop() else: next_node = TerminalNode() self._stack.append(SomeExpression(CurrentNode(next_node))) else: pass
def match(self, root_value: object, current_value: object) -> Generator[MatchData, None, None]: if isinstance(current_value, dict) and (self.index in current_value): return [ MatchData(SubscriptNode(TerminalNode(), [self]), root_value, current_value[self.index]) ] else: return []
def exitJsonpath(self, ctx:JSONPathParser.JsonpathContext): if ctx.getToken(JSONPathParser.ROOT_VALUE, 0) is not None: if bool(ctx.subscript()): next_node = self._stack.pop() else: next_node = TerminalNode() self._stack.append(RootNode(next_node)) else: raise ValueError()
def match(self, root_value: object, current_value: object) -> Generator[MatchData, None, None]: if isinstance(current_value, list): if self.index < 0: new_index = self.index + len(current_value) if (new_index >= 0) and (new_index < len(current_value)): return [ MatchData(SubscriptNode(TerminalNode(), [self]), root_value, current_value[new_index]) ] else: return [] elif self.index < len(current_value): return [ MatchData(SubscriptNode(TerminalNode(), [self]), root_value, current_value[self.index]) ] else: return [] else: return []
def exitSubscript(self, ctx:JSONPathParser.SubscriptContext): if ctx.getToken(JSONPathParser.RECURSIVE_DESCENT, 0) is not None: if bool(ctx.subscript()): next_node = self._stack.pop() else: next_node = TerminalNode() if bool(ctx.subscriptableBareword()): subscriptable_nodes = [self._stack.pop()] elif bool(ctx.subscriptables()): subscriptable_nodes = self._stack.pop() else: raise ValueError() self._stack.append(RecursiveDescentNode(SubscriptNode(next_node, subscriptable_nodes))) elif ctx.getToken(JSONPathParser.SUBSCRIPT, 0) is not None: if bool(ctx.subscript()): next_node = self._stack.pop() else: next_node = TerminalNode() if bool(ctx.subscriptableBareword()): subscriptable_nodes = [self._stack.pop()] else: raise ValueError() self._stack.append(SubscriptNode(next_node, subscriptable_nodes)) else: if bool(ctx.subscript()): next_node = self._stack.pop() else: next_node = TerminalNode() if bool(ctx.subscriptables()): subscriptable_nodes = self._stack.pop() else: raise ValueError() self._stack.append(SubscriptNode(next_node, subscriptable_nodes))
def test_cloudevents(self): with open(os.path.join('test_files', 'events.json'), 'r') as io: d = json.load(io) s = '$[?(@["eventID"] and @["eventType"] = "org.pacifica.metadata.ingest" and @["source"] = "/pacifica/metadata/ingest")]["data"][*][?(@["destinationTable"] = "TransactionKeyValue")]["key"]' p = Path.parse_str(s) n = RootNode( SubscriptNode( SubscriptNode( SubscriptNode( SubscriptNode( SubscriptNode(TerminalNode(), [ ObjectIndexSubscript('key'), ]), [ FilterSubscript( EqualBinaryOperatorExpression( CurrentNode( SubscriptNode( TerminalNode(), [ ObjectIndexSubscript( 'destinationTable'), ])), 'TransactionKeyValue')), ]), [ WildcardSubscript(), ]), [ ObjectIndexSubscript('data'), ]), [ FilterSubscript( AndVariadicOperatorExpression([ SomeExpression( CurrentNode( SubscriptNode(TerminalNode(), [ ObjectIndexSubscript('eventID'), ])), ), EqualBinaryOperatorExpression( CurrentNode( SubscriptNode(TerminalNode(), [ ObjectIndexSubscript('eventType'), ])), 'org.pacifica.metadata.ingest'), EqualBinaryOperatorExpression( CurrentNode( SubscriptNode(TerminalNode(), [ ObjectIndexSubscript('source'), ])), '/pacifica/metadata/ingest'), ])), ])) self.assertEqual(n, p.root_node) self.assertEqual(s, str(p)) match_data_list = list(p.match(d)) self.assertEqual([ MatchData( Path.parse_str('$["data"][4]["key"]').root_node, d, 'Tag'), MatchData( Path.parse_str('$["data"][5]["key"]').root_node, d, 'Taggy'), MatchData( Path.parse_str('$["data"][6]["key"]').root_node, d, 'Taggier'), ], match_data_list) for match_data in match_data_list: new_match_data_list = list( match_data.node.match(match_data.root_value, match_data.current_value)) self.assertEqual([match_data], new_match_data_list)
def setUp(self): root_value = { 'hello': 'Hello, world!', 'languages': [ 'en-GB', 'en-US', ], } current_value = root_value['hello'] self._state = [ { '__jsonpath__': '', 'node': TerminalNode(), 'root_value': root_value, 'current_value': current_value, 'match_data_list': [ MatchData(TerminalNode(), root_value, current_value), ], }, { '__jsonpath__': '$', 'node': RootNode(TerminalNode()), 'root_value': root_value, 'current_value': current_value, 'match_data_list': [ MatchData(RootNode(TerminalNode()), root_value, root_value), ], }, { '__jsonpath__': '@', 'node': CurrentNode(TerminalNode()), 'root_value': root_value, 'current_value': current_value, 'match_data_list': [ MatchData(CurrentNode(TerminalNode()), root_value, current_value), ], }, { '__jsonpath__': '[]', 'node': SubscriptNode(TerminalNode(), []), 'root_value': root_value, 'current_value': current_value, 'match_data_list': [], }, { '__jsonpath__': '[?(@)]', 'node': SubscriptNode(TerminalNode(), [ FilterSubscript(SomeExpression(CurrentNode( TerminalNode()))) ]), 'root_value': root_value, 'current_value': current_value, 'match_data_list': [ MatchData(TerminalNode(), root_value, current_value), ], }, { '__jsonpath__': '[?(@),?(@)]', 'node': SubscriptNode(TerminalNode(), [ FilterSubscript(SomeExpression(CurrentNode( TerminalNode()))), FilterSubscript(SomeExpression(CurrentNode( TerminalNode()))) ]), 'root_value': root_value, 'current_value': current_value, 'match_data_list': [ MatchData(TerminalNode(), root_value, current_value), MatchData(TerminalNode(), root_value, current_value), ], }, { '__jsonpath__': '[*]', 'node': SubscriptNode(TerminalNode(), [WildcardSubscript()]), 'root_value': root_value, 'current_value': current_value, 'match_data_list': [], }, { '__jsonpath__': '[*]', 'node': SubscriptNode(TerminalNode(), [WildcardSubscript()]), 'root_value': root_value, 'current_value': root_value, 'match_data_list': [ MatchData( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('hello')]), root_value, root_value['hello']), MatchData( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('languages')]), root_value, root_value['languages']), ], }, { '__jsonpath__': '["languages"][*]', 'node': SubscriptNode( SubscriptNode(TerminalNode(), [WildcardSubscript()]), [ObjectIndexSubscript('languages')]), 'root_value': root_value, 'current_value': root_value, 'match_data_list': [ MatchData( SubscriptNode( SubscriptNode(TerminalNode(), [ArrayIndexSubscript(0)]), [ObjectIndexSubscript('languages')]), root_value, root_value['languages'][0]), MatchData( SubscriptNode( SubscriptNode(TerminalNode(), [ArrayIndexSubscript(1)]), [ObjectIndexSubscript('languages')]), root_value, root_value['languages'][1]), ], }, { '__jsonpath__': '["hello","languages"]', 'node': SubscriptNode(TerminalNode(), [ ObjectIndexSubscript('hello'), ObjectIndexSubscript('languages') ]), 'root_value': root_value, 'current_value': root_value, 'match_data_list': [ MatchData( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('hello')]), root_value, root_value['hello']), MatchData( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('languages')]), root_value, root_value['languages']), ], }, { '__jsonpath__': '..', 'node': RecursiveDescentNode(TerminalNode()), 'root_value': root_value, 'current_value': current_value, 'match_data_list': [ MatchData(TerminalNode(), root_value, current_value), ], }, { '__jsonpath__': '..', 'node': RecursiveDescentNode(TerminalNode()), 'root_value': root_value, 'current_value': root_value, 'match_data_list': [ MatchData(TerminalNode(), root_value, root_value), MatchData( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('hello')]), root_value, root_value['hello']), MatchData( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('languages')]), root_value, root_value['languages']), MatchData( SubscriptNode( SubscriptNode(TerminalNode(), [ArrayIndexSubscript(0)]), [ObjectIndexSubscript('languages')]), root_value, root_value['languages'][0]), MatchData( SubscriptNode( SubscriptNode(TerminalNode(), [ArrayIndexSubscript(1)]), [ObjectIndexSubscript('languages')]), root_value, root_value['languages'][1]), ], }, { '__jsonpath__': '..[?(@)]', 'node': RecursiveDescentNode( SubscriptNode(TerminalNode(), [ FilterSubscript( SomeExpression(CurrentNode(TerminalNode()))) ])), 'root_value': root_value, 'current_value': root_value, 'match_data_list': [ MatchData(TerminalNode(), root_value, root_value), MatchData( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('hello')]), root_value, root_value['hello']), MatchData( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('languages')]), root_value, root_value['languages']), MatchData( SubscriptNode( SubscriptNode(TerminalNode(), [ArrayIndexSubscript(0)]), [ObjectIndexSubscript('languages')]), root_value, root_value['languages'][0]), MatchData( SubscriptNode( SubscriptNode(TerminalNode(), [ArrayIndexSubscript(1)]), [ObjectIndexSubscript('languages')]), root_value, root_value['languages'][1]), ], }, { '__jsonpath__': '..[*]', 'node': RecursiveDescentNode( SubscriptNode(TerminalNode(), [WildcardSubscript()])), 'root_value': root_value, 'current_value': root_value, 'match_data_list': [ MatchData( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('hello')]), root_value, root_value['hello']), MatchData( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('languages')]), root_value, root_value['languages']), MatchData( SubscriptNode( SubscriptNode(TerminalNode(), [ArrayIndexSubscript(0)]), [ObjectIndexSubscript('languages')]), root_value, root_value['languages'][0]), MatchData( SubscriptNode( SubscriptNode(TerminalNode(), [ArrayIndexSubscript(1)]), [ObjectIndexSubscript('languages')]), root_value, root_value['languages'][1]), ], }, { '__jsonpath__': '..["hello"]', 'node': RecursiveDescentNode( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('hello')])), 'root_value': root_value, 'current_value': root_value, 'match_data_list': [ MatchData( SubscriptNode(TerminalNode(), [ObjectIndexSubscript('hello')]), root_value, root_value['hello']), ], }, { '__jsonpath__': '..[0]', 'node': RecursiveDescentNode( SubscriptNode(TerminalNode(), [ArrayIndexSubscript(0)])), 'root_value': root_value, 'current_value': root_value, 'match_data_list': [ MatchData( SubscriptNode( SubscriptNode(TerminalNode(), [ArrayIndexSubscript(0)]), [ObjectIndexSubscript('languages')]), root_value, root_value['languages'][0]), ], }, ]
def match(self, root_value:object, current_value:object) -> Generator[MatchData, None, None]: if self.expression.evaluate(root_value, current_value): return [MatchData(TerminalNode(), root_value, current_value)] else: return []