參考

陣列

陣列用於有序的元素。在 JSON 中,陣列中的每個元素可以是不同的類型。

特定語言資訊:
Python
Ruby
Objective-C
Swift

在 Python 中,「陣列」類似於 listtuple 類型,具體取決於用法。但是,Python 標準函式庫中的 json 模組始終使用 Python 列表來表示 JSON 陣列。

schema
{ "type": "array" }
資料
[1, 2, 3, 4, 5]
符合 schema
資料
[3, "different", { "types": "of values" }]
符合 schema
資料
{"Not": "an array"}
不符合 schema

在 JSON 中,陣列通常有兩種使用方式

  • 列表驗證:任意長度的序列,其中每個項目都符合相同的 schema
  • 元組驗證:固定長度的序列,其中每個項目可能具有不同的 schema。在這種用法中,每個項目的索引(或位置)對於如何解釋該值具有意義。(這種用法在某些程式語言中通常會給予一個完全獨立的類型,例如 Python 的 tuple)。

項目

列表驗證適用於任意長度的陣列,其中每個項目都符合相同的 schema。對於這種類型的陣列,請將 items 關鍵字設定為單一 schema,該 schema 將用於驗證陣列中的所有項目。

在以下範例中,我們定義陣列中的每個項目都是一個數字

schema
{ "type": "array", "items": { "type": "number" }}
資料
[1, 2, 3, 4, 5]
符合 schema

單一「非數字」會導致整個陣列無效。

資料
[1, 2, "3", 4, 5]
不符合 schema

空陣列永遠有效。

資料
[]
符合 schema

元組驗證

當陣列是一組項目集合,且每個項目都有不同的結構描述,並且每個項目的序數索引都有意義時,元組驗證非常有用。

例如,您可以使用 4 元組的形式來表示街道地址,例如 1600 Pennsylvania Avenue NW

資料
[number, street_name, street_type, direction]

[數字, 街道名稱, 街道類型, 方向]

這些欄位各自將會有不同的結構描述。

  • number:地址號碼。必須是數字。
  • street_name:街道名稱。必須是字串。
  • street_type:街道類型。應該是來自固定值集合的字串。
  • direction:地址的城市象限。應該是來自不同值集合的字串。

為了做到這一點,我們使用 prefixItems 關鍵字。prefixItems 是一個陣列,其中每個項目都是一個結構描述,對應於文件陣列的每個索引。也就是說,一個陣列的第一個元素驗證輸入陣列的第一個元素,第二個元素驗證輸入陣列的第二個元素,依此類推。

草稿特定資訊
在 Draft 4 - 2019-09 中,元組驗證由 items 關鍵字的另一種形式處理。當 items 是一個結構描述陣列而不是單一結構描述時,它的行為方式與 prefixItems 的行為方式相同。

這是範例結構描述

schema
{ "type": "array", "prefixItems": [ { "type": "number" }, { "type": "string" }, { "enum": ["Street", "Avenue", "Boulevard"] }, { "enum": ["NW", "NE", "SW", "SE"] } ]}
資料
[1600, "Pennsylvania", "Avenue", "NW"]
符合 schema

「Drive」不是可接受的街道類型之一

資料
[24, "Sussex", "Drive"]
不符合 schema

這個地址缺少街道號碼

資料
["Palais de l'Élysée"]
不符合 schema

不提供所有項目是可以的

資料
[10, "Downing", "Street"]
符合 schema

而且,預設情況下,在末尾添加額外項目也是可以的

資料
[1600, "Pennsylvania", "Avenue", "NW", "Washington"]
符合 schema

額外項目

items 關鍵字可以用來控制在元組中,除了 prefixItems 中定義的項目之外,是否有額外的項目是有效的。 items 關鍵字的值是一個 schema,所有額外的項目都必須通過這個 schema 的驗證才能使該關鍵字驗證通過。

草案 4 - 2019-09
在 2020-12 草案之前,你會使用 additionalItems 關鍵字來約束元組中的額外項目。它的運作方式與 items 相同,只是名稱改變了。
草案 6 - 2019-09
在草案 6 - 2019-09 中,如果同一個 schema 中沒有「元組驗證」的 items 關鍵字存在,則會忽略 additionalItems 關鍵字。

在這裡,我們將重複使用上面的範例 schema,但將 items 設定為 false,這樣做會產生不允許元組中有多餘項目的效果。

schema
{ "type": "array", "prefixItems": [ { "type": "number" }, { "type": "string" }, { "enum": ["Street", "Avenue", "Boulevard"] }, { "enum": ["NW", "NE", "SW", "SE"] } ], "items": false}
資料
[1600, "Pennsylvania", "Avenue", "NW"]
符合 schema

可以不用提供所有的項目

資料
[1600, "Pennsylvania", "Avenue"]
符合 schema

但是,由於 itemsfalse,我們不能提供額外的項目

資料
[1600, "Pennsylvania", "Avenue", "NW", "Washington"]
不符合 schema

您可以使用非布林值的 schema 來表達更複雜的約束,以限制額外項目可以擁有的值。在這種情況下,我們可以說允許額外的項目,只要它們都是字串即可

schema
{ "type": "array", "prefixItems": [ { "type": "number" }, { "type": "string" }, { "enum": ["Street", "Avenue", "Boulevard"] }, { "enum": ["NW", "NE", "SW", "SE"] } ], "items": { "type": "string" }}

額外的字串項目是可以的...

資料
[1600, "Pennsylvania", "Avenue", "NW", "Washington"]
符合 schema

...但其他任何東西都不行

資料
[1600, "Pennsylvania", "Avenue", "NW", 20500]
不符合 schema

未評估的項目

2019-09 草案新增

unevaluatedItems 關鍵字主要在您想要在陣列中新增或禁止額外項目時很有用。

unevaluatedItems 適用於任何未被 itemsprefixItemscontains 關鍵字評估的值。正如 unevaluatedProperties 僅影響物件中的屬性unevaluatedItems 僅影響陣列中的項目

注意!「未評估 (unevaluated)」這個詞並不表示「未經 itemsprefixItemscontains 評估」。 「未評估 (unevaluated)」的意思是「未成功評估」,或「評估結果不為真」。

如同 items,如果您將 unevaluatedItems 設定為 false,您可以禁止陣列中出現額外的項目。

schema
{ "prefixItems": [ { "type": "string" }, { "type": "number" } ], "unevaluatedItems": false}

在這裡,所有數值都經過評估。Schema 通過驗證。

資料
["foo", 42]
符合 schema

但在此處,schema 無法通過驗證,因為 "unevaluatedItems": false 指定不應存在額外的數值。

資料
["foo", 42, null]
不符合 schema

請注意,items 不會「看到」同一個子架構allOfanyOfoneOf 的任何實例。 因此,在下一個範例中,items 會忽略 allOf,因此驗證失敗。

schema
{ "allOf": [{ "prefixItems": [{ "type": "boolean" }, { "type": "string" }] }], "items": { "const": 2 }}
資料
[true, "a", 2]
不符合 schema

但如果你將 items 替換為 unevaluatedItems,則相同的陣列會驗證通過。

schema
{ "allOf": [{ "prefixItems": [{ "type": "boolean" }, { "type": "string" }] }], "unevaluatedItems": { "const": 2 }}
資料
[true, "a", 2]
符合 schema

你也可以建立一個「半封閉」的結構:當你想要保留前兩個參數,但在某些情況下也想加入更多參數時,這個結構會很有用。(在某些地方「封閉」為兩個參數,當你需要時,則「開放」給更多參數。)

schema
{ "$id": "https://example.com/my-tuple", "type": "array", "prefixItems": [ { "type": "boolean" }, { "type": "string" } ],
"$defs": { "closed": { "$anchor": "closed", "$ref": "#", "unevaluatedItems": false } }}

這裡的綱要「關閉」為兩個陣列項目。之後你可以使用 $ref 並像這樣新增另一個項目

schema
{ "$id": "https://example.com/my-extended-tuple", "$ref": "https://example.com/my-tuple", "prefixItems": [ { "type": "boolean" }, { "type": "string" }, { "type": "number" } ],
"$defs": { "closed": { "$anchor": "closed", "$ref": "#", "unevaluatedItems": false } }}

因此,當您只需要兩個項目時,您會參考 my-tuple#closed,而當您需要三個項目時,則會參考 my-tuple#extended

包含

在草案 6 中新增

雖然 items 綱要必須對陣列中的每個項目都有效,但 contains 綱要只需要對陣列中的一個或多個項目驗證即可。

schema
{ "type": "array", "contains": { "type": "number" }}

單一的 "number" 就足以讓這個驗證通過

資料
["life", "universe", "everything", 42]
符合 schema

但如果沒有數字,就會失敗

資料
["life", "universe", "everything", "forty-two"]
不符合 schema

當然,全部都是數字也可以

資料
[1, 2, 3, 4, 5]
符合 schema

minContains / maxContains

2019-09 草案新增

minContainsmaxContains 可以與 contains 一起使用,以進一步指定 schema 符合 contains 約束的次數。這些關鍵字可以是任何非負數,包括零。

schema
{ "type": "array", "contains": { "type": "number" }, "minContains": 2, "maxContains": 3}

符合 minContains 失敗

資料
["apple", "orange", 2]
不符合 schema
資料
["apple", "orange", 2, 4]
符合 schema
資料
["apple", "orange", 2, 4, 8]
符合 schema

不符合 maxContains 的條件

資料
["apple", "orange", 2, 4, 8, 16]
不符合 schema

長度

可以使用 minItemsmaxItems 關鍵字來指定陣列的長度。每個關鍵字的值必須是非負數。這些關鍵字無論是進行列表驗證元組驗證都有效。

schema
{ "type": "array", "minItems": 2, "maxItems": 3}
資料
[]
不符合 schema
資料
[1]
不符合 schema
資料
[1, 2]
符合 schema
資料
[1, 2, 3]
符合 schema
資料
[1, 2, 3, 4]
不符合 schema

獨特性

schema 可以確保陣列中的每個項目都是唯一的。只需將 uniqueItems 關鍵字設定為 true

schema
{ "type": "array", "uniqueItems": true}
資料
[1, 2, 3, 4, 5]
符合 schema
資料
[1, 2, 3, 3, 4]
不符合 schema

空陣列總是會通過驗證

資料
[]
符合 schema

需要協助嗎?

您覺得這些文件有幫助嗎?

幫助我們改進文件!

在 JSON Schema,我們重視文件貢獻,如同其他類型的貢獻一樣!

仍然需要協助嗎?

學習 JSON Schema 通常令人困惑,但別擔心,我們在這裡提供協助!