@@ -25,3 +25,153 @@ related:
2525 - vocabulary : applicator
2626 keyword : not
2727---
28+
29+ The {{<link keyword =" anyOf " vocabulary =" applicator " >}} keyword restricts
30+ instances to validate against _ at least one_ (but potentially multiple) of the
31+ given subschemas. This keyword represents a [ logical
32+ disjunction] ( https://en.wikipedia.org/wiki/Logical_disjunction ) (OR)
33+ operation, as instances are valid if they satisfy the constraints of one or
34+ more subschemas (the union of the constraints).
35+
36+ {{<learning-more >}}Keep in mind that when collecting annotations, the JSON
37+ Schema implementation will need to exhaustively evaluate every subschema past
38+ the first match instead of short-circuiting validation, potentially
39+ introducing additional computational overhead.
40+
41+ For example, consider 3 subschemas where the instance validates against the
42+ first. When not collecting annotations, validation will stop after evaluating
43+ the first subschema. However, when collecting annotations, evaluation will
44+ have to proceed past the first subschema in case the others emit
45+ annotations.{{</learning-more >}}
46+
47+ This keyword is equivalent to the ` || ` operator found in most programming
48+ languages. For example:
49+
50+ ``` c
51+ bool valid = A || B || C;
52+ ```
53+
54+ As a reference, the following boolean [ truth
55+ table] ( https://en.wikipedia.org/wiki/Truth_table ) considers the evaluation
56+ result of this keyword given 3 subschemas: A, B, and C.
57+
58+ <table class =" table table-borderless border " >
59+ <thead >
60+ <tr class="table-light">
61+ <th><code>anyOf</code></th>
62+ <th>Subschema A</th>
63+ <th>Subschema B</th>
64+ <th>Subschema C</th>
65+ </tr>
66+ </thead >
67+ <tbody >
68+ <tr class="table-danger">
69+ <td class="fw-bold"><i class="bi bi-x-circle-fill me-1"></i> Invalid</td>
70+ <td><i class="bi bi-x-circle"></i> Invalid</td>
71+ <td><i class="bi bi-x-circle"></i> Invalid</td>
72+ <td><i class="bi bi-x-circle"></i> Invalid</td>
73+ </tr>
74+ <tr class="table-success">
75+ <td class="fw-bold"><i class="bi bi-check-circle-fill me-1"></i> Valid</td>
76+ <td><i class="bi bi-x-circle"></i> Invalid</td>
77+ <td><i class="bi bi-x-circle"></i> Invalid</td>
78+ <td><i class="bi bi-check-circle"></i> Valid</td>
79+ </tr>
80+ <tr class="table-success">
81+ <td class="fw-bold"><i class="bi bi-check-circle-fill me-1"></i> Valid</td>
82+ <td><i class="bi bi-x-circle"></i> Invalid</td>
83+ <td><i class="bi bi-check-circle"></i> Valid</td>
84+ <td><i class="bi bi-x-circle"></i> Invalid</td>
85+ </tr>
86+ <tr class="table-success">
87+ <td class="fw-bold"><i class="bi bi-check-circle-fill me-1"></i> Valid</td>
88+ <td><i class="bi bi-x-circle"></i> Invalid</td>
89+ <td><i class="bi bi-check-circle"></i> Valid</td>
90+ <td><i class="bi bi-check-circle"></i> Valid</td>
91+ </tr>
92+ <tr class="table-success">
93+ <td class="fw-bold"><i class="bi bi-check-circle-fill me-1"></i> Valid</td>
94+ <td><i class="bi bi-check-circle"></i> Valid</td>
95+ <td><i class="bi bi-x-circle"></i> Invalid</td>
96+ <td><i class="bi bi-x-circle"></i> Invalid</td>
97+ </tr>
98+ <tr class="table-success">
99+ <td class="fw-bold"><i class="bi bi-check-circle-fill me-1"></i> Valid</td>
100+ <td><i class="bi bi-check-circle"></i> Valid</td>
101+ <td><i class="bi bi-x-circle"></i> Invalid</td>
102+ <td><i class="bi bi-check-circle"></i> Valid</td>
103+ </tr>
104+ <tr class="table-success">
105+ <td class="fw-bold"><i class="bi bi-check-circle-fill me-1"></i> Valid</td>
106+ <td><i class="bi bi-check-circle"></i> Valid</td>
107+ <td><i class="bi bi-check-circle"></i> Valid</td>
108+ <td><i class="bi bi-x-circle"></i> Invalid</td>
109+ </tr>
110+ <tr class="table-success">
111+ <td class="fw-bold"><i class="bi bi-check-circle-fill me-1"></i> Valid</td>
112+ <td><i class="bi bi-check-circle"></i> Valid</td>
113+ <td><i class="bi bi-check-circle"></i> Valid</td>
114+ <td><i class="bi bi-check-circle"></i> Valid</td>
115+ </tr>
116+ </tbody >
117+ </table >
118+
119+ ## Examples
120+
121+ {{<schema ` A schema that constrains object instances to require at least one of the given properties ` >}}
122+ {
123+ "$schema": "https://json-schema.org/draft/2019-09/schema ",
124+ "anyOf": [
125+ { "required": [ "foo" ] },
126+ { "required": [ "bar" ] }
127+ ]
128+ }
129+ {{</schema >}}
130+
131+ {{<instance-pass ` A value that only matches the first subschema is valid ` >}}
132+ { "foo": 1 }
133+ {{</instance-pass >}}
134+
135+ {{<instance-pass ` A value that only matches the second subschema is valid ` >}}
136+ { "bar": 2 }
137+ {{</instance-pass >}}
138+
139+ {{<instance-pass ` A value that matches every subschema is valid ` >}}
140+ { "foo": 1, "bar": 2 }
141+ {{</instance-pass >}}
142+
143+ {{<instance-fail ` A value that does not match any of the subschemas is invalid ` >}}
144+ { "extra": 4 }
145+ {{</instance-fail >}}
146+
147+ {{<schema ` A schema that constrains instances with logical disjunctions that emit annotations ` >}}
148+ {
149+ "$schema": "https://json-schema.org/draft/2019-09/schema ",
150+ "anyOf": [
151+ { "title": "Branch #1 ", "type": "number" },
152+ { "title": "Branch #2 ", "type": "string" },
153+ { "title": "Branch #3 ", "type": "integer" }
154+ ]
155+ }
156+ {{</schema >}}
157+
158+ {{<instance-pass ` A value that only matches the first subschema receives the first annotation ` >}}
159+ 3.14
160+ {{</instance-pass >}}
161+
162+ {{<instance-annotation >}}
163+ { "keyword": "/anyOf/0/title", "instance": "", "value": [ "Branch #1 " ] }
164+ {{</instance-annotation >}}
165+
166+ {{<instance-pass ` A value that matches two subschemas receives both annotations ` >}}
167+ 12345
168+ {{</instance-pass >}}
169+
170+ {{<instance-annotation >}}
171+ { "keyword": "/anyOf/0/title", "instance": "", "value": [ "Branch #1 " ] }
172+ { "keyword": "/anyOf/2/title", "instance": "", "value": [ "Branch #3 " ] }
173+ {{</instance-annotation >}}
174+
175+ {{<instance-fail ` A value that does not match any of the subschemas is invalid and receives no annotations ` >}}
176+ { "foo": 1 }
177+ {{</instance-fail >}}
0 commit comments