python庫JsonSchema驗證JSON數(shù)據(jù)結(jié)構(gòu)使用詳解
JSON Schema是一個用于驗證JSON數(shù)據(jù)結(jié)構(gòu)的強大工具, 我查看并學習了JSON Schema的官方文檔, 做了詳細的記錄, 分享一下。
我們可以使用JSON Schema在后續(xù)做接口測試中做詳細的數(shù)據(jù)值的校驗, 數(shù)據(jù)類型校驗, json數(shù)據(jù)結(jié)構(gòu)的校驗。
jsonschema用以標注和驗證JSON文檔的元數(shù)據(jù)的文檔
官方文檔地址jsonschema
簡單實例
有一個簡單的json數(shù)據(jù), 根據(jù)json數(shù)據(jù)格式編寫jsonschema, 然后校驗json數(shù)據(jù)每個字段是否是規(guī)定類型。
import jsonschema json_data = [ { 'pm10': 24, 'city': '珠海', 'time': '2016-10-23 13:00:00' }, { 'pm10': 24, 'city': '深圳', 'time': '2016-10-21 13:00:00' }, { 'pm10': '21', 'city': '廣州', 'time': '2016-10-23 13:00:00' } ] json_schema = { 'type': 'array', 'items': { 'type': 'object', 'properties': { 'pm10': { 'type': 'number', }, 'city': { 'type': 'string', 'enum': ['珠海', '深圳'] }, 'time': { 'type': 'string' } } } } try: jsonschema.validate(json_data, json_schema) except jsonschema.ValidationError as ex: msg = ex print(ex)
type關(guān)鍵字
type關(guān)鍵字是json模式的基礎(chǔ), 指定架構(gòu)的數(shù)據(jù)類型。JSON Schema的核心定義了以下基本類型:
- string
- Numeric types
- object
- array
- boolean
- null
這些類型在Python中對應的類型如下, 下表將JavaScript類型的名稱映射到Python的相關(guān)類型:
JavaScript | Python |
string | string |
number | int/float |
object | dict |
array | list |
boolean | bool |
null | none |
type關(guān)鍵字可以是一個字符串或數(shù)組:
- 如果它是一個字符串, 那么它是上面一個基本能類型的名稱
- 如果它是一個數(shù)組, 它必須是一個字符串數(shù)組, 其中每個字符串是其中一個基本類型的名稱, 每個元素都是唯一的。在這種情況下, 如果json代碼段與任何給定類型匹配,則改代碼段有效。
以下做個type關(guān)鍵字的簡單示例:
{“type”: “number”}
定義某個字段類型是number, 如果是 40, 43.0這樣是校驗通過的如果是”43”, 包含數(shù)字的字符串這樣是無法校驗通過的.
{“type”: [“number”, ‘string’]}
定義某個字段類型是number或string中一種如果是43, 或者 “我和你” 這樣是校驗通過的如果是[43, “我和你”], 這樣是不通過的, 因為不接受結(jié)構(gòu)化數(shù)據(jù)類型。
object關(guān)鍵字
在Python中, 對象對應的類型是dict類型。
屬性 properties
使用properties關(guān)鍵字定義對象上的屬性(鍵值對)。例如, 我們要為由數(shù)字, 街道名稱和街道類型組成的地址定義一個簡單的模式
{ “type” : “object” , “properties” : { “number” : { “type” : “number” }, “street_name” : { “type” : “string” }, “street_type” : { “type” : “string” , “enum” : [ “Street” , “Avenue” , “Boulevard” ] } } }
必需屬性
默認情況下,properties不需要由關(guān)鍵字定義的屬性。但是,可以使用required關(guān)鍵字提供所需屬性的列表。
required關(guān)鍵字接受一個或多個字符串的數(shù)組。每個字符串必須是唯一的。
在以下定義用戶記錄的示例模式中,我們要求每個用戶都有一個名稱和電子郵件地址,但我們不介意他們是否提供了他們的地址或電話號碼:
{ “type” : “object” , “properties” : { “name” : { “type” : “string” }, “email” : { “type” : “string” }, “address” : { “type” : “string” }, “telephone” : { “type” : “string” } }, “required” : [ “name” , “email”] }
大小
可以使用minProperties和maxProperties關(guān)鍵字限制對象上的屬性數(shù) 。這些中的每一個都必須是非負整數(shù)。
{ “type” : “object” , “minProperties” : 2 , “maxProperties” : 3 }
數(shù)組屬性
數(shù)組用于有序元素。
在Python中, array類似于 list或tuple類型,具體取決于用法。
例如: [1,2,3,4,5]
[2, ‘dd’]
items
數(shù)組的元素可能是任何東西, 但是,根據(jù)某些模式驗證數(shù)組的項通常很有用。這里使用items和additionalItems關(guān)鍵字完成。
在JSON中, 通常使用兩種方式的數(shù)據(jù)
- 列表驗證: 任意長度的序列, 其中每個元素匹配相同的模式
- 元組驗證: 一個固定長度的序列,其中每個項目可能具有不同的模式, 在此用法中, 每個項目的索引(位置)對于如何解釋值是有意義的,例如Python的tuple。
List validation
列表驗證對于任意長度的數(shù)組非常有用, 其中每個項都匹配相同的模式, 對于此類數(shù)組, 將items關(guān)鍵字設(shè)置為單個模式, 用該模式來驗證數(shù)組中的所有項。
注意: 這時items是單個模式, additionalItems關(guān)鍵字沒有意義, 不應該使用它。
例如下面的事例中我們定義數(shù)組中每個項都是一個數(shù)字
{ “type” : “array” , "items": { "type": "number" } }
如果是[1,2,3,4,5], pass
如果是[1,2,3,’5’, 6] , false
如果是[], pass
Tuple validation
當數(shù)組是項目集合時, 就需要元組驗證。其中每個項目都有不同的模式, 并且每個項目的序數(shù)索引是有意義的。
例如: 街道地址這樣表示
1600 Pennsylvania Avenue NW就有4中type[number, streent_name, street_type, direction]
每個字段都有不同的架構(gòu)
- number: 地址編號, 必須是數(shù)字
- street_name: 街道的名稱, 必須是字符串
- street_type: 街道的類型, 應該是一組固定值的字符串
- direction: 地址的位置, 應該是來自不同值集的字符串
為此我們將items關(guān)鍵字設(shè)置成一個數(shù)組, 其中每個項目都是一個與文檔數(shù)組的每個索引相對應的模式, 也就是一個數(shù)組, 第一個元素模式驗證輸入數(shù)組的第一個元素. 第二個元素模式驗證輸入數(shù)組的第二個元素, 等等
示例:
{ “type” : “array” , “items” : [ { “type” : “number” }, { “type” : “string” }, { “type” : “string” , “enum” : [ “Street” “ , ”Avenue“ , ”Boulevard“ ] }, { ”type“ : ”string“ , ”enum“ : [ ”NW“ , ”NE“ , “SW” , “SE” ] } ] }
如果是[1600, “賓夕法尼亞”, ‘Street’, “NW”], pass如果是[10,’等等’, ‘等等’], false并且在默認情況下, 添加其他項目也可以:[ 1600 , “賓夕法尼亞州” , “Street” , “NW” , “華盛頓” ]
additionalItems關(guān)鍵字控制是否有效有超出了在架構(gòu)中定義的數(shù)組的其他項目,如果設(shè)置為false, 則會不允許數(shù)組中的額外項。
長度
可以使用minItems和 maxItems關(guān)鍵字指定數(shù)組的長度。每個關(guān)鍵字的值必須是非負數(shù)。無論是進行List驗證還是Tuple驗證,這些關(guān)鍵字都有效。示例:
{ “type” : “array” , “minItems” : 2 , “maxItems” : 3 }
唯一性
使用uniqueItems關(guān)鍵字設(shè)置為true, 則數(shù)組中的每個項都是唯一的。
通用關(guān)鍵字
元數(shù)據(jù)
json模式包含幾個關(guān)鍵字,title,description和default, 不嚴格用來校驗格式,但用來描述模式的一部分。在title和description管家你必須是字符串
枚舉值
enum關(guān)鍵字用于限制值, 以一個固定的一組值, 它必須是一個必須包含一個元素的數(shù)組,其中每個元素都是唯一的。
{ ‘type’ : ‘string’, ‘enum’: [‘red’, ‘green’]}
如果檢驗字段的值在枚舉中是通過的, 如果不是無法校驗通過。
組合模式
JSON Schema包含一些用于將模式組合在一起的關(guān)鍵字,這并不意味著組合來自多個文件或JSON樹的模式, 盡管這些工具有助于實現(xiàn)這一點,并在結(jié)構(gòu)化復雜模式中進行了描述。
例如, 在以下的模式, anyOf關(guān)鍵字用于表示給定值可能對任何給定的子模式有效。第一個子模式需要一個最大長度為5的字符串。第二個子模式需要一個最小值為0的數(shù)字。只要一個值對這些模式中的任何一個進行驗證,它就被認為整個組合模式有效。
{ ‘anyOf’: [ {‘type’: ‘string’, ‘maxLength’: 5}, {‘type’:’string’, ‘minimum’: 0 }]}
用于組合模式的關(guān)鍵字是:
- allOf: 必須對所有子模式有效
- anyOf: 必須對任何子模式有效(一個或多個)
- oneOf: 必須僅對其中一個子模式有效
anyOf
要進行驗證anyOf,給定數(shù)據(jù)必須對任何(一個或多個)給定子模式有效。
{ “anyOf” : [ { “type” : “string” }, { “type” : “number” } ] }
如果是 “您好”, pass如果是 33, pass如果是 [‘ddd’, 33], false
oneOf
要進行驗證oneOf,給定數(shù)據(jù)必須僅對其中一個給定子模式有效。
{ “oneOf” : [ { “type” : “number” , “multipleOf” : 5 }, { “type” : “number” , “multipleOf” : 3 } ] }
如果是5的倍數(shù), pass如果是3的倍數(shù), pass如果是5和3的倍數(shù), false
allOf
要進行驗證allOf,給定數(shù)據(jù)必須對所有給定的子模式有效。
{ “allOf” : [ { “type” : “string” }, { “maxLength” : 5 } ] }
$schema關(guān)鍵字
該$schema關(guān)鍵字用于聲明JSON片段實際上是JSON模式的一部分。它還聲明了針對該模式編寫的JSON Schema標準的哪個版本。
建議所有JSON模式都有一個$schema條目,該條目必須位于根目錄下。因此,大多數(shù)情況下,您需要在架構(gòu)的根目錄下:
“$ schema” : “http://json-schema.org/schema#”
正則表達式
該模式和模式屬性關(guān)鍵字使用正則表達式來表示約束。使用的正則表達式語法來自JavaScript(具體為ECMA 262)。但是,并未廣泛支持該完整語法,因此建議您堅持使用下述語法的子集。
- 單個unicode字符(下面的特殊字符除外)與自身匹配。
- ^:僅匹配字符串的開頭。
- $:僅匹配字符串的末尾。
- (…):將一系列正則表達式分組到單個正則表達式中。
- |:匹配|符號前面或后面的正則表達式。
- [abc]:匹配方括號內(nèi)的任何字符。
- [a-z]:匹配字符范圍。
- [^abc]:匹配未列出的任何字符。
- [^a-z]:匹配范圍之外的任何字符。
- +:匹配前一個正則表達式的一個或多個重復。
- *:匹配前面正則表達式的零次或多次重復。
- ?:匹配前一個正則表達式的零次或一次重復。
- +?,?,??:的,+和?預選賽都是貪婪的; 它們匹配盡可能多的文本。有時這種行為是不可取的,您希望匹配盡可能少的字符。
- {x}:完全x匹配前面正則表達式的出現(xiàn)次數(shù)。
- {x,y}:匹配前面正則表達式的至少x和最y多次出現(xiàn)。
- {x,}:匹配x前面正則表達式的出現(xiàn)次數(shù)或更多。
- {x}?,{x,y}?,{x,}?:上述表達式的惰性版本。
示例:
{ “type” : “string” , “pattern” : “^(\\([0-9] {3} \\))?[0-9]{3}-[0-9] {4} $ “ }
如果是 “555-1212”, pass如果是“(888)555-1212” , pass如果是“(888)555-1212分機532” , false
構(gòu)建復雜的模式
重用
有些模式可能是在幾個地方都是通用的, 如果每次都重寫會使模式更加冗長,以后更新也會很復雜, 我們可以用重用的方式來做。例如:定義客戶記錄, 每個客戶都有可能同時擁有送貨地址和賬單地址, 地址總是相同的, 有街道地址, 城市, 州名。
定義地址模式:
{ “type” : “object” , “properties” : { “street_address” : { “type” : “string” }, “city” : { “type” : “string” }, “state” : { “type” : “string” } }, “required” : [ “street_address” , “city” ,“state” ] }
我們重用上面的模式, 將其放在父模式下, 名為definitions:
{ “definitions” : { “address” : { “type” : “object” , “properties” : { “street_address” :{“type” :“string”}, “city” : { “type” : “string” }, “state” : { “type” : “string” } }, “required” :[“street_address” ,“city”,“州”] } } }
然后我們使用$ref關(guān)鍵字從其他地方引用此架構(gòu)片段, 指向此模塊的位置
{ “$ ref” : “#/ definitions / address” }
值 $ref 是一個名為 JSON Pointer的格式的字符串。
‘#’引用當前文檔,‘/’遍歷文檔中對象中的鍵, 因此
“#/ definitions / address” 意味著:
- 轉(zhuǎn)到文檔的根目錄
- 找到秘鑰的值”definitions”
- 在該對象中, 找到鍵的值”address”
$ref也可以是相對或絕對的URI, 例如:
{ “$ ref” : “definitions.json#/ address” }
以上就是python庫JsonSchema驗證JSON數(shù)據(jù)結(jié)構(gòu)使用詳解的詳細內(nèi)容,更多關(guān)于JsonSchema驗證JSON數(shù)據(jù)結(jié)構(gòu)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
在Python操作時間和日期之a(chǎn)sctime()方法的使用
這篇文章主要介紹了在Python操作時間和日期之a(chǎn)sctime()方法的使用,是Python入門學習中的基礎(chǔ)知識,需要的朋友可以參考下2015-05-05python?Seaborn繪制統(tǒng)計圖全面指南(直方圖散點圖小提琴圖熱力圖相關(guān)系數(shù)圖多張合并)
這篇文章主要介紹了python?Seaborn繪制統(tǒng)計圖全面指南,包括直方圖,散點圖,小提琴圖,熱力圖,相關(guān)系數(shù)圖及多張圖合并的實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助2024-01-01python 寫函數(shù)在一定條件下需要調(diào)用自身時的寫法說明
這篇文章主要介紹了python 寫函數(shù)在一定條件下需要調(diào)用自身時的寫法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06Python如何使用標準庫tmpfile庫創(chuàng)建臨時文件
這篇文章主要介紹了Python如何使用標準庫tmpfile庫創(chuàng)建臨時文件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02簡單介紹Python中的try和finally和with方法
這篇文章主要介紹了Python中的try和finally和with方法,是Python學習當中的基礎(chǔ)知識,需要的朋友可以參考下2015-05-05