Python_json資料檢索與定位之jsonPath類庫

授客發表於2018-11-24

json資料檢索與定位之jsonPath類庫

 

by:授客 QQ:1033553122

 

實踐環境

win7 64

Python 3.4.0

 

jsonpath_ng-1.4.3-py2.py3-none-any.whl

下載地址:

https://pypi.org/project/jsonpath-ng/#files

https://pan.baidu.com/s/1AdbGqz1brNYBOqmIbWaAYg

 

 

使用詳解

官方例項

>>> from jsonpath_ng import jsonpath, parse

>>> jsonpath_expr = parse(`foo[*].baz`)

 

# 提取值

>>> [match.value for match in jsonpath_expr.find({`foo`:[{`baz`:1}, {`baz`:2}]})]

[1, 2]

 

# 獲取匹配值對應的路徑

>>> [str(match.full_path) for match in jsonpath_expr.find({`foo`: [{`baz`: 1}, {`baz`: 2}]})]

[`foo.[0].baz`, `foo.[1].baz`]

 

# 自動提供id

>>> [match.value for match in parse(`foo[*].id`).find({`foo`: [{`id`: `bizzle`}, {`baz`: 3}]})]

[`bizzle`]

>>> jsonpath.auto_id_field = `id`

>>> [match.value for match in parse(`foo[*].id`).find({`foo`: [{`id`: `bizzle`}, {`baz`: 3}]})]

[`foo.bizzle`, `foo.[1]`]

 

# 擴充套件功能之一 命名操作符 `parent`

>>> [match.value for match in parse(`a.*.b.`parent`.c`).find({`a`: {`x`: {`b`: 1, `c`: `number one`}, `y`: {`b`: 2, `c`: `number two`}}})]

[`number one`, `number two`]

>>> [`number two`, `number one`]

 

使用擴充套件的解析器

好處是有更強大的擴充套件功能

>>> from jsonpath_ng.ext import parse

 

>>> jsonpath_expr = parse(`foo[*].baz`)

jsonpath 語法

基礎語法(Atomic expressions)

$            根物件

`this`      當前物件

`foo`       More generally, this syntax allows “named operators” to extend JSONPath is arbitrary ways

field       指定具體的欄位

[ field ]   同field

[ idx ]     陣列訪問 Array access, described below (this is always unambiguous with field access)

 

例子

獲取根物件

>>> parse(`$`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}]})

[DatumInContext(value={`key2`: {`id`: 2}, `key3`: [{`id`: 3}, {`name`: `shouke`}], `key1`: {`id`: 1}}, path=Root(), context=None)]

 

>>> [match.value for match in parse(`$`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}]})]

[{`key2`: {`id`: 2}, `key3`: [{`id`: 3}, {`name`: `shouke`}], `key1`: {`id`: 1}}]

 

獲取一級鍵對應的值

>>> [match.value for match in parse(`key1`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}]})]

[{`id`: 1}]

 

>>> [match.value for match in parse(`[key1]`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}]})]

[{`id`: 1}]

 

 

# 注意:單獨使用 filed [filed] 語法,field僅支援字典的一級鍵

[{`key2`: {`id`: 2}, `key3`: [{`id`: 3}, {`name`: `shouke`}], `key1`: {`id`: 1}}]

>>> [match.value for match in parse(`id`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}]})]

[]

 

# 注意:單獨使用 filed [filed] 語法,根物件必須是字典,不能是陣列

>>> [match.value for match in parse(`[key1]`).find([{`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}]}])]

[]

 

陣列訪問

>>> [match.value for match in parse(`[0]`).find([{`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}]}])]

[{`key2`: {`id`: 2}, `key3`: [{`id`: 3}, {`name`: `shouke`}], `key1`: {`id`: 1}}]

jsonpath操作符

jsonpath1 . jsonpath2     匹配jsonpath2,並且父節點匹配jsonpath1的所有節點(All nodes matched by jsonpath2 starting at any node matching jsonpath1) 注意:僅針對字典可用

注:有無空格不影響,比如jsonpath1.jsonpath2 下同   

 

jsonpath [ whatever ]     如果是字典,同jsonpath.whatever,如果是陣列,則表示按索引訪問陣列

 

jsonpath1 .. jsonpath2    匹配jsonpath2,並且由匹配jsonpath1的父節點派生的所有節點

 

jsonpath1 where jsonpath2     匹配jsonpath1並且攜帶一個匹配jsonpath2直接子節點(非派生子節點)的所有節點(Any nodes matching jsonpath1 with a child matching jsonpath2)

 

jsonpath1 | jsonpath2       匹配jsonpath1,或者jsonpath2的所有節點的集合(注:有時候結果似乎和描述不符,具體見例子

 

 

 

 

例子

jsonpath1 . jsonpath2  

>>> [match.value for match in parse(`key1.id`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}]})]

[1]

 

jsonpath [ whatever ]  

>>> [match.value for match in parse(`key1[id]`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}]})]

[1]

>>> [match.value for match in parse(`key3[0]`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}]})]

[{`id`: 3}]

 

jsonpath1 .. jsonpath2 

>>> [match.value for match in parse(`key3..id`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:{`key4`:{`key5`:{`id`:3, `name`:`shouke`}}}})]

[3]

>>> [match.value for match in parse(`key3..id`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}, {`id`:4, `name`:`keshou`}]})]

[3, 4]

 

jsonpath1 where jsonpath2  

>>> [match.value for match in parse(`key2 where id`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}, {`id`:4, `name`:`keshou`

[{`id`: 2}]

 

注意:匹配jsonpath2的必須是直接子節點

>>> [match.value for match in parse(`key3 where id`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}, {`id`:4, `name`:`keshou`

[]

 

>>> [match.value for match in parse(`key3 where id`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:{`key4`:{`key5`:{`id`:3, `name`:`shouke`}}}})]

[]

 

jsonpath1 | jsonpath2  

>>> [match.value for match in parse(`key1 | key3 `).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:{`key4`:{`key5`:{`id`:3, `name`:`shouke`}}}})]

[{`id`: 1}, {`key4`: {`key5`: {`name`: `shouke`, `id`: 3}}}]

 

>>> [match.value for match in parse(`key1 | key3.key4 `).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:{`key4`:{`key5`:{`id`:3, `name`:`shouke`}}}})]

[{`key5`: {`name`: `shouke`, `id`: 3}}]

 

欄位說明(field)

fieldname   來自當前物件的欄位名稱

“fieldname” 同上,允許fieldname中包含指定字元

`fieldname` 同上

*            任意欄位名稱

field , field   指定多個欄位

例子

*

>>> [match.value for match in parse(`key1.*`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:{`key4`:{`key5`:{`id`:3, `name`:`shouke`}}}})]

[1]

 

注意:如果是jsonpath1.* 返回的是最後層級的值

>>> [match.value for match in parse(`key3.*`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:{`key4`:{`key5`:{`id`:3, `name`:`shouke`}}}})]

[{`key5`: {`name`: `shouke`, `id`: 3}}]

 

 

>>> [match.value for match in parse(`key3.*`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}, {`id`:4, `name`:`keshou`}]})]

[]

 

>>> [match.value for match in parse(`key1, key2, key3`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}, {`id`:4, `name`:`kesh

[{`id`: 1}, {`id`: 2}, [{`id`: 3}, {`name`: `shouke`}, {`name`: `keshou`, `id`: 4}]]

>>> [match.value for match in parse(`*.*[*]`).find({`root`:{`key`:[{`id`:`tizza`}, {`name`:`hizza`}]}})]

[{`id`: `tizza`}, {`name`: `hizza`}]

 

field , field   指定多個欄位

>>> [match.value for match in parse(`key1, key2, key3`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}, {`id`:4, `name`:`keshou`}]

[{`id`: 1}, {`id`: 2}, [{`id`: 3}, {`name`: `shouke`}, {`name`: `keshou`, `id`: 4}]]

 

陣列索引說明(idx)

[n] 陣列索引

[start?:end?]   含義同python的陣列切片,注意:陣列索引不包含end,可以不指定start, end,或者兩者之一

[*] 任意索引,表示返回整個陣列元素,等同於[:]

 

例子

 

[*]

[match.value for match in parse(`key3[*]`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}, {`id`:4, `name`:`keshou`}]})]

[{`id`: 3}, {`name`: `shouke`}, {`name`: `keshou`, `id`: 4}]

 

[start?:end?]

>>> [match.value for match in parse(`key3[0:1]`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}, {`id`:4, `name`:`keshou`}]})]

[{`id`: 3}]

 

>>> [match.value for match in parse(`key3[0:]`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}, {`id`:4, `name`:`keshou`}]})]

[{`id`: 3}, {`name`: `shouke`}, {`name`: `keshou`, `id`: 4}]

 

>>> [match.value for match in parse(`key3[:1]`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}, {`id`:4, `name`:`keshou`}]})]

[{`id`: 3}]

 

>>> [match.value for match in parse(`key3[:]`).find({`key1`:{`id`: 1}, `key2`:{`id`: 2}, `key3`:[{`id`:3}, {`name`:`shouke`}, {`id`:4, `name`:`keshou`}]})]

[{`id`: 3}, {`name`: `shouke`}, {`name`: `keshou`, `id`: 4}]

>>> 

 

 

更多功能參考官方文件

 

參考連結

https://pypi.org/project/jsonpath-ng/#files

 

相關文章