def query_doc(coll, jpath): """ Performs a query in collection using the JSONPath. For example, return all documents satisfying the given JSONPath expression. i.e. all documents that contain a non-empty value at the given JSONPath >>> query_doc(coll, '$.app.address') # return all documents with a non-empty address: >>> query_doc(coll, '$..address') :param coll: collection being queried :type jpath: string :param jpath: JSONPath at which to update the fragment :rtype: list :return: a list of map (a list of JSON documents) """ # initially, using brute force approach: # 1. first get all docs, docs = coll.find() # 2. then filter those that have a match of jpath results = filter(lambda x: jsonpath.jsonpath(x, jpath), docs) return results
def append_doc(coll, doc, doc_fragment, jpath): """ Appends to the document fragment at the given JSONPath key. Creates the parent key(s) and document if necessary. :param coll: collection for which document is being updated :type doc: dict :param doc: JSON document to append to :type doc_fragment: map :param doc_fragment: document fragment to append :type jpath: string :param jpath: JSONPath at which to append the fragment :return: index at which append was done. 0 if a new list node was created as a result of append. """ # modify the doc modify_doc(doc, doc_fragment, jpath, append=True) _do_save(coll, doc) # logger.debug('update_doc: %s, filter: %s' % (doc, filt)) subdocs = jsonpath.jsonpath(doc, jpath) # print('append_doc: %s' % subdocs) if subdocs: # append happened at index {len - 1) ret = len(subdocs[0]) - 1 else: ret = 0 return ret
def modify_doc(doc, doc_fragment, jpath, append=False): """ Modifies doc by replacing doc fragment at given JSONPath by the given doc fragment. Creates the parent key(s) and document if necessary. :type doc: dict :param doc: JSON document to update :type doc_fragment: dict or string :param doc_fragment: document fragment with which to update :type jpath: string :param jpath: JSONPath at which to update the fragment :return: number of nodes modified """ logger.debug('modify_doc: doc_fragment, jpath: %s, %s' % (doc_fragment, jpath)) # eval doesn't work with ObjectId. # we therefore replace ObjectId with string # {'_id': ObjectId('506da6b025dc9a250b000000'), id = doc.get('_id') if id and not isinstance(id, str): doc['_id'] = str(id) # identify map subnode to modify/update subdocs = jsonpath.jsonpath(doc, jpath) if append and subdocs and len(subdocs) > 1: raise BadParameterError('append can be performed only on JSONPath that matches a single node') if append and (not subdocs or (subdocs and not isinstance(subdocs[0], list))): # create a new list _put(doc, jpath, []) subdocs = jsonpath.jsonpath(doc, jpath) assert(subdocs) if not subdocs: logger.debug('modify_doc: %s applied to %s yielded no results' % (jpath, doc)) # create the given doc_fragment at jpath _put(doc, jpath, doc_fragment) ret = 1 else: ret = jsonpath_replace(doc, doc_fragment, jpath, append) # restore original id # if id: # doc['_id'] = id return ret
def extract_fragment_from_doc(doc, jpath): """ Extract a fragment from document at the given JSONPath. Usage: Extract address fragment from document >>> subdoc = extract_fragment_from_doc(doc, '$.app.address') # return all addresses in the document: >>> extract_fragment_from_doc(doc, '$..address') :param doc: doc from which fragment is being extracted :type jpath: string :param jpath: JSONPath at which to update the fragment :rtype: map :return: a JSON document """ return jsonpath.jsonpath(doc, jpath)
def unset_doc(coll, doc, jpath): """ Removes node at given JSONPath :return: True if node was unset, False if no action was taken since there was no code found under given jpath """ id = doc.get('_id') if id and not isinstance(id, str): doc['_id'] = str(id) # identify map subnode to modify/update subdocs = jsonpath.jsonpath(doc, jpath) if subdocs: count = jsonpath_replace(doc, None, jpath) _do_save(coll, doc) else: # logger.debug('unset_doc: %s applied to %s yielded no results, therefore nothing removed from doc' % \ # (jpath, doc)) count = 0 return count
def path_jsonpath(data, expr): """Path expression engine using jsonpath""" if jsonpath is None: raise NotImplementedError("jsonpath is not installed") return jsonpath.jsonpath(data, expr, use_eval=False) or []
def get_data(self, path): data = jsonpath.jsonpath(self.get_message(), expr=path) return data
print(jsonpath(dict, '$..students[0,1,3]')) # 输出 [{'student_id': '1', 'name': 'bob', 'sex': 'male', 'age': 6}, {'student_id': '2', 'name': 'amy', 'sex': 'female', 'age': 6}] print(jsonpath(dict, '$..students[:2]')) # 输出 [{'student_id': '1', 'name': 'bob', 'sex': 'male', 'age': 6}, {'student_id': '2', 'name': 'amy', 'sex': 'female', 'age': 6}] # 获取students的最后一条数据 print(jsonpath(dict, '$..students[-1:]')) # 输出 [{'student_id': '3', 'name': 'pery', 'sex': 'male', 'age': 5}] road_name=jsonpath.jsonpath(content2,'$..name') #print(road_name) road_location=jsonpath.jsonpath(content2,'$..dir') road_index=jsonpath.jsonpath(content2,'$..index') road_speed=jsonpath.jsonpath(content2,'$..speed') road_traveltime=jsonpath.jsonpath(content2,'$..travelTime') road_date=jsonpath.jsonpath(content2,'$..delayTime') #print(road_name+"w2,"+road_location) # print(road_name+","+road_location+","+road_index+","+road_speed+","+road_traveltime+","+road_date))
def jsonpath_replace(doc, fragment, jpath, append=False): """ Performs a JSONPath update transaction. Implement the update part of JSONPath, using its facility to retrieve paths to JSONPath extraction results, rather than results themselves, and them building a Python statement from the paths that are executed to perform assignments of fragment to individual nodes in the dict tree. If there are more than than one nodes found in the dict tree, all of them will be assigned the fragment. If fragment is None, the node(s) will be removed. >>> tdoc = {'web': [{'instance': 'i-ba2911c0', 'address': '54.242.12.1'}, {'instance': 'this is not the one', 'address': '54.242.12.3'}, {'instance': 'this is the one', 'address': '54.242.12.3'}, {'instance': 'i-ba2911c0', 'address': '54.242.12.4'}], 'app': {'instance': 'i-30340c4a', 'address': '107.22.57.90'}, 'proxy': {'instance': 'i-ba2119c0', 'address': '50.16.150.144'}, 'database': {}} >>> jpath = 'web[2].address' >>> fragment = '111.111.111.111' >>> jsonpath_replace(tdoc, jpath, fragment) doc['web'][2]['address'] = fragment >>> tdoc {'web': [{'instance': 'i-ba2911c0', 'address': '54.242.12.1'}, {'instance': 'this is not the one', 'address': '54.242.12.3'}, {'instance': 'this is the one', 'address': '111.111.111.111'}, {'instance': 'i-ba2911c0', 'address': '54.242.12.4'}], 'app': {'instance': 'i-30340c4a', 'address': '107.22.57.90'}, 'proxy': {'instance': 'i-ba2119c0', 'address': '50.16.150.144'}, 'database': {}} :type doc: dict :param doc: json doc :type fragment: str or dict :param fragment: fragment to replace JSONPath node with :type jpath: str :param jpath: JSONPath string :return: number of assignments performed """ ipath = jsonpath.jsonpath(doc, jpath, result_type='IPATH') # print ipath # for example: # 1) web[2].address -> [[web', '2', 'address']] # or, given a certain doc: # 2) $..book[?(@.price<10)]', '$;..;book;?(@.price<10) # -> [['store', 'book', '0'], ['store', 'book', '2']] docname = 'doc' rhs = 'fragment' statements = [] # build all assignment statements if ipath: for ip in ipath: expr = docname for w in ip: if w.isdigit(): expr += "[%s]" % w else: expr += "['%s']" % w if append: # e.g. # >>> if isinstance(doc['web'], list): doc['web'].append('a') # ... else: doc['web'] = ['a'] statement = 'if isinstance(%s, list): %s.append(fragment)\nelse: %s = [fragment]' % \ (expr, expr, expr) expr = statement elif fragment is None: expr = "del %s" % expr else: expr += " = %s" % rhs statements.append(expr) # example result statements: # for case 1): # ["doc['web'][2]['address'] = fragment"] # for case 2): # # print statements for s in statements: exec(s) return len(statements)
# from jsonpath import jsonpath # # jsonpath里真有jsonpath模块jsonpath # data = {'key1': {'key2': {'key3': {'key4': {'key5': {'key6':'python'}}}}}} # #键值索引 # print(data['key1']['key2']['key3']['key4']['key5']['key6']) # # print(jsonpath(data,'$..key6')[0]) # print(jsonpath(data,'$.key1.key2.key3.key4.key5.key6')[0]) # from jsonpath import jsonpath data = {"username1": {"us": {"a": "1"}}} print(data["username1"]["us"]) print(jsonpath(data, '$..username1')) print(jsonpath.jsonpath(data, '$.username1')) # import requests # import jsonpath # import json # # headers = { # 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36' # } # response = requests.get('https://www.lagou.com/lbs/getAllCitySearchLabels.json', headers=headers) # dict_data = json.loads(response.content.decode()) # print(dict_data) # print(jsonpath.jsonpath(dict_data, '$..name'))