22Author : zhangxianbing1
33Date : 2020-12-27 09:22:14
44LastEditors : zhangxianbing1
5- LastEditTime : 2020-12-31 17:02:04
5+ LastEditTime : 2020-12-31 18:05:36
66Description : JSONPath
77"""
88__version__ = "1.0.0"
3030REP_DOUBLEDOT = re .compile (r"\.\." )
3131REP_DOT = re .compile (r"(?<!\.)\.(?!\.)" )
3232
33-
33+ # operators
3434REP_SLICE_CONTENT = re .compile (r"^(-?\d*)?:(-?\d*)?(:-?\d*)?$" )
3535REP_SELECT_CONTENT = re .compile (r"^([\w.]+)(,[\w.]+)+$" )
36- # operators
37- REP_UNION_OP = re .compile (r"(?<!\\)," )
38-
39- REP_FILTER_FIELD = re .compile (
36+ REP_FILTER_CONTENT = re .compile (
4037 r"@\.(.*?)(?=<=|>=|==|!=|>|<| in| not| is)|len\(@\.(.*?)\)"
4138)
4239
@@ -47,6 +44,18 @@ def concat(x, y, con=SEP):
4744 return f"{ x } { con } { y } "
4845
4946
47+ def _getattr (obj : dict , path : str ):
48+ r = obj
49+ for k in path .split ("." ):
50+ try :
51+ r = r .get (k )
52+ except (AttributeError , KeyError ) as err :
53+ print (err )
54+ return None
55+
56+ return r
57+
58+
5059class ExprSyntaxError (Exception ):
5160 pass
5261
@@ -150,7 +159,7 @@ def _trace(self, obj, istep: int):
150159
151160 Args:
152161 obj ([type]): current operating object
153- idx (int): current operation specified by index in self.ops
162+ istep (int): current operation specified by index in self.steps
154163 """
155164
156165 # store
@@ -201,20 +210,32 @@ def _trace(self, obj, istep: int):
201210 # filter
202211 if step .startswith ("?(" ) and step .endswith (")" ):
203212 step = step [2 :- 1 ]
204- step = REP_FILTER_FIELD .sub (self ._f_brackets , step )
213+ step = REP_FILTER_CONTENT .sub (self ._f_brackets , step )
205214 self ._traverse (self ._filter , obj , istep + 1 , step )
206215 return
207216
208217 # sort
209- # elif key:
210- # pass
218+ if step .startswith ("/(" ) and step .endswith (")" ):
219+ if isinstance (obj , list ):
220+ step = step [2 :- 1 ]
221+ for sortby in step .split ("," )[::- 1 ]:
222+ if sortby .startswith ("~" ):
223+ obj .sort (
224+ key = lambda t , k = sortby : _getattr (t , k [1 :]), reverse = True
225+ )
226+ else :
227+ obj .sort (key = lambda t , k = sortby : _getattr (t , k ))
228+
229+ self ._traverse (self ._trace , obj , istep + 1 )
230+ return
211231
212232
213233if __name__ == "__main__" :
214234 # JSONPath("$.a.'b.c'.'d e'.[f,g][h][*][j.k][l m][2:4]..d", result_type="FIELD")
215235 with open ("test/data/2.json" , "rb" ) as f :
216236 d = json .load (f )
217- JSONPath (
218- '$.book[?(@.title=="Herman Melville" or @.title=="Evelyn Waugh")].title'
219- ).parse (d )
237+ # JSONPath(
238+ # '$.book[?(@.title=="Herman Melville" or @.title=="Evelyn Waugh")].title'
239+ # ).parse(d)
220240 # JSONPath("$..price").parse(d)
241+ JSONPath ("$.book[/(price)].price" ).parse (d )
0 commit comments