參考
陣列
陣列用於有序的元素。在 JSON 中,陣列中的每個元素可以是不同的類型。
在 Python 中,「陣列」類似於 list
或 tuple
類型,具體取決於用法。但是,Python 標準函式庫中的 json
模組始終使用 Python 列表來表示 JSON 陣列。
在 JSON 中,陣列通常有兩種使用方式
- 列表驗證:任意長度的序列,其中每個項目都符合相同的 schema。
- 元組驗證:固定長度的序列,其中每個項目可能具有不同的 schema。在這種用法中,每個項目的索引(或位置)對於如何解釋該值具有意義。(這種用法在某些程式語言中通常會給予一個完全獨立的類型,例如 Python 的
tuple
)。
項目
列表驗證適用於任意長度的陣列,其中每個項目都符合相同的 schema。對於這種類型的陣列,請將 items
關鍵字設定為單一 schema,該 schema 將用於驗證陣列中的所有項目。
在以下範例中,我們定義陣列中的每個項目都是一個數字
單一「非數字」會導致整個陣列無效。
空陣列永遠有效。
元組驗證
當陣列是一組項目集合,且每個項目都有不同的結構描述,並且每個項目的序數索引都有意義時,元組驗證非常有用。
例如,您可以使用 4 元組的形式來表示街道地址,例如 1600 Pennsylvania Avenue NW
:
[數字, 街道名稱, 街道類型, 方向]
這些欄位各自將會有不同的結構描述。
number
:地址號碼。必須是數字。street_name
:街道名稱。必須是字串。street_type
:街道類型。應該是來自固定值集合的字串。direction
:地址的城市象限。應該是來自不同值集合的字串。
為了做到這一點,我們使用 prefixItems
關鍵字。prefixItems
是一個陣列,其中每個項目都是一個結構描述,對應於文件陣列的每個索引。也就是說,一個陣列的第一個元素驗證輸入陣列的第一個元素,第二個元素驗證輸入陣列的第二個元素,依此類推。
items
關鍵字的另一種形式處理。當 items
是一個結構描述陣列而不是單一結構描述時,它的行為方式與 prefixItems
的行為方式相同。這是範例結構描述
「Drive」不是可接受的街道類型之一
這個地址缺少街道號碼
不提供所有項目是可以的
而且,預設情況下,在末尾添加額外項目也是可以的
額外項目
items
關鍵字可以用來控制在元組中,除了 prefixItems
中定義的項目之外,是否有額外的項目是有效的。 items
關鍵字的值是一個 schema,所有額外的項目都必須通過這個 schema 的驗證才能使該關鍵字驗證通過。
additionalItems
關鍵字來約束元組中的額外項目。它的運作方式與 items
相同,只是名稱改變了。items
關鍵字存在,則會忽略 additionalItems
關鍵字。在這裡,我們將重複使用上面的範例 schema,但將 items
設定為 false
,這樣做會產生不允許元組中有多餘項目的效果。
可以不用提供所有的項目
但是,由於 items
是 false
,我們不能提供額外的項目
您可以使用非布林值的 schema 來表達更複雜的約束,以限制額外項目可以擁有的值。在這種情況下,我們可以說允許額外的項目,只要它們都是字串即可
額外的字串項目是可以的...
...但其他任何東西都不行
未評估的項目
unevaluatedItems
關鍵字主要在您想要在陣列中新增或禁止額外項目時很有用。
unevaluatedItems
適用於任何未被 items
、prefixItems
或 contains
關鍵字評估的值。正如 unevaluatedProperties
僅影響物件中的屬性,unevaluatedItems
僅影響陣列中的項目。
注意!「未評估 (unevaluated)」這個詞並不表示「未經 items
、prefixItems
或 contains
評估」。 「未評估 (unevaluated)」的意思是「未成功評估」,或「評估結果不為真」。
如同 items
,如果您將 unevaluatedItems
設定為 false
,您可以禁止陣列中出現額外的項目。
在這裡,所有數值都經過評估。Schema 通過驗證。
但在此處,schema 無法通過驗證,因為 "unevaluatedItems": false
指定不應存在額外的數值。
請注意,items
不會「看到」同一個子架構中 allOf
、 anyOf
或 oneOf
的任何實例。 因此,在下一個範例中,items
會忽略 allOf
,因此驗證失敗。
但如果你將 items
替換為 unevaluatedItems
,則相同的陣列會驗證通過。
你也可以建立一個「半封閉」的結構:當你想要保留前兩個參數,但在某些情況下也想加入更多參數時,這個結構會很有用。(在某些地方「封閉」為兩個參數,當你需要時,則「開放」給更多參數。)
"$defs": { "closed": { "$anchor": "closed", "$ref": "#", "unevaluatedItems": false } }}
這裡的綱要「關閉」為兩個陣列項目。之後你可以使用 $ref
並像這樣新增另一個項目
"$defs": { "closed": { "$anchor": "closed", "$ref": "#", "unevaluatedItems": false } }}
因此,當您只需要兩個項目時,您會參考 my-tuple#closed
,而當您需要三個項目時,則會參考 my-tuple#extended
。
包含
雖然 items
綱要必須對陣列中的每個項目都有效,但 contains
綱要只需要對陣列中的一個或多個項目驗證即可。
單一的 "number" 就足以讓這個驗證通過
但如果沒有數字,就會失敗
當然,全部都是數字也可以
minContains / maxContains
minContains
和 maxContains
可以與 contains
一起使用,以進一步指定 schema 符合 contains
約束的次數。這些關鍵字可以是任何非負數,包括零。
符合 minContains
失敗
不符合 maxContains
的條件
長度
可以使用 minItems
和 maxItems
關鍵字來指定陣列的長度。每個關鍵字的值必須是非負數。這些關鍵字無論是進行列表驗證或元組驗證都有效。
獨特性
schema 可以確保陣列中的每個項目都是唯一的。只需將 uniqueItems
關鍵字設定為 true
。
空陣列總是會通過驗證