@@ -240,7 +240,7 @@ A schema that itself describes a schema is called a meta-schema. Meta-schemas
240
240
are used to validate JSON Schemas and specify the set of keywords those schemas
241
241
are using.
242
242
243
- #### Root Schema and Subschemas and Resources {#root}
243
+ #### Root Schema, Subschemas, and Resources {#root}
244
244
245
245
A JSON Schema resource is a schema which is
246
246
[ canonically] ( https://www.rfc-editor.org/info/rfc6596 ) identified by an
@@ -334,9 +334,8 @@ NCNameChar = NCNameStartChar / "-" / "." / DIGIT
334
334
All fragment identifiers that do not match the JSON Pointer syntax MUST be
335
335
interpreted as plain name fragment identifiers.
336
336
337
- Defining and referencing a plain name fragment identifier within an
338
- ` application/schema+json ` document are specified in the [ ` $anchor `
339
- keyword] ( #anchors ) section.
337
+ Defining a plain name fragment identifier within an ` application/schema+json `
338
+ document is specified in the [ ` $anchor ` keyword] ( #anchors ) section.
340
339
341
340
## General Considerations
342
341
@@ -950,33 +949,24 @@ an [absolute IRI](https://www.rfc-editor.org/rfc/rfc3987.html#section-2.2)
950
949
951
950
#### Defining location-independent identifiers {#anchors}
952
951
953
- Using JSON Pointer fragments requires knowledge of the structure of the schema.
954
- When writing schema documents with the intention to provide re-usable schemas,
955
- it may be preferable to use a plain name fragment that is not tied to any
956
- particular structural location. This allows a subschema to be relocated without
957
- requiring JSON Pointer references to be updated.
958
-
959
- The ` $anchor ` and ` $dynamicAnchor ` keywords are used to specify such fragments.
960
- They are identifier keywords that can only be used to create plain name
961
- fragments, rather than absolute IRIs as seen with ` $id ` .
962
-
963
- ` $anchor ` defines a reference target for ` $ref ` . The fragment defined by this
964
- keyword is appended to the IRI of the schema resource containing it. As
965
- discussed in {{id-keyword}}, this is either the nearest ` $id ` in the same or an
966
- ancestor schema object, or the base IRI for the document as determined according
967
- to [ RFC 3987] [ rfc3987 ] and
968
- [ RFC 3986] [ rfc3986 ] .
969
-
970
- In contrast, ` $dynamicAnchor ` operates independently of resource IRIs and is
971
- instead dependent on the dynamic scope of the evaluation. ` $dynamicAnchor `
972
- defines a reference target for the ` $dynamicRef ` keyword. This advanced feature
973
- makes it easier to extend recursive schemas such as the meta-schemas, without
974
- imposing any particular semantics on that extension. See {{dynamic-ref}} for
975
- details.
976
-
977
- In most cases, the normal fragment behavior both suffices and is more intuitive.
978
- Therefore it is RECOMMENDED that ` $anchor ` be used to create plain name
979
- fragments unless there is a clear need for ` $dynamicAnchor ` .
952
+ Using JSON Pointers in IRI fragments to reference subschemas couples the IRI to
953
+ the structure of the schema. Using plain names in IRI fragments to identify
954
+ subschemas is sometimes preferable because it is not tied to a particular
955
+ structural location. This allows a subschema to be relocated without requiring
956
+ references to be updated.
957
+
958
+ The ` $anchor ` and ` $dynamicAnchor ` keywords are used to define
959
+ location-independent identifiers for subschemas within a schema resource.
960
+
961
+ ` $anchor ` defines a plain name fragment identifier that can be used in IRI
962
+ fragments as an alternative to JSON Pointers. See {{fragments}}.
963
+
964
+ ` $dynamicAnchor ` defines a different kind of identifier that only has meaning
965
+ when used as a value for ` $dynamicRef ` . It's not a fragment identifier that can
966
+ be used in an IRI. ` $dynamicRef ` uses a syntax similar to a fragment-only IRI,
967
+ but the semantics are different. Unlike IRIs, the fragment identifies the
968
+ primary resource (the schema resource) in addition to the secondary resource
969
+ (the subschema within that schema resource). See {{dynamic-ref}} for details.
980
970
981
971
If present, the value of these keywords MUST be a string and MUST conform to the
982
972
plain name fragment identifier syntax defined in {{fragments}}.[ ^ 4 ]
@@ -989,9 +979,9 @@ in a IRI. See below for full examples.
989
979
990
980
A schema MAY (and likely will) have multiple IRIs, but there is no way for an
991
981
IRI to identify more than one schema. When multiple schemas attempt to identify
992
- as the same IRI through the use of ` $id ` , ` $anchor ` , ` $dynamicAnchor ` , or any
993
- other mechanism, implementations SHOULD raise an error condition. Otherwise the
994
- result is undefined, and even if documented will not be interoperable.
982
+ as the same IRI through the use of ` $id ` , ` $anchor ` , or any other mechanism,
983
+ implementations SHOULD raise an error condition. Otherwise the result is
984
+ undefined, and even if documented will not be interoperable.
995
985
996
986
#### Schema References {#references}
997
987
@@ -1001,13 +991,10 @@ applicators, applying the referenced schema to the instance.
1001
991
1002
992
##### Direct References with ` $ref ` {#ref}
1003
993
1004
- The ` $ref ` keyword is an applicator that is used to reference a statically
1005
- identified schema. Its results are the results of the referenced schema.[ ^ 5 ]
994
+ The ` $ref ` keyword is an applicator that is used to reference a schema. Its
995
+ evaluation results are the results of evaluating the referenced schema.
1006
996
1007
- [ ^ 5 ] : Note that this definition of how the results are determined means that
1008
- other keywords can appear alongside of ` $ref ` in the same schema object.
1009
-
1010
- The value of the ` $ref ` keyword MUST be a string which is a IRI reference.
997
+ The value of the ` $ref ` keyword MUST be a string which is an IRI reference.
1011
998
Resolved against the current IRI base, it produces the IRI of the schema to
1012
999
apply. This resolution is safe to perform on schema load, as the process of
1013
1000
evaluating an instance cannot change how the reference resolves.
@@ -1019,28 +1006,29 @@ default to operating offline.
1019
1006
1020
1007
##### Dynamic References with ` $dynamicRef ` {#dynamic-ref}
1021
1008
1022
- The ` $dynamicRef ` keyword is an applicator that allows for deferring the full
1023
- resolution until runtime, at which point it is resolved each time it is
1024
- encountered while evaluating an instance.
1025
-
1026
- Together with ` $dynamicAnchor ` , ` $dynamicRef ` implements a cooperative extension
1027
- mechanism that is primarily useful to to create open schemas, where
1028
- ` $dynamicRef ` defines the extension point and ` $dynamicAnchor ` defines the
1029
- target.
1009
+ The ` $dynamicRef ` keyword is an applicator that is used when the referencing
1010
+ schema might need to override where a reference in the referenced schema will
1011
+ resolve. This is useful for authoring a recursive schema that can be extended or
1012
+ a generic schema such as a list whose items are defined by the referencing
1013
+ schema.
1030
1014
1031
1015
The value of the ` $dynamicRef ` property MUST be formatted as a valid
1032
- [ IRI plain name fragment] ( #fragments ) .[ ^ 3 ]
1016
+ [ fragment-only IRI] ( #fragments ) .[ ^ 3 ]
1017
+
1018
+ [ ^ 3 ] : ` $dynamicAnchor ` defines the anchor with plain text, e.g. ` foo ` . Although,
1019
+ for historical reasons the value of ` $dynamicRef ` still uses an fragment-only
1020
+ IRI syntax, e.g. ` #foo ` .
1033
1021
1034
- [ ^ 3 ] : ` $dynamicAnchor ` defines the anchor with plain text, e.g. ` foo ` . Although
1035
- the value of ` $dynamicRef ` is not an IRI fragment, for historical reasons, the
1036
- value still uses an IRI fragment syntax, e.g. ` #foo ` .
1022
+ Resolution of ` $dynamicRef ` begins by identifying the outermost schema resource
1023
+ in the [ dynamic scope] ( #scopes ) which defines a matching ` $dynamicAnchor ` .[ ^ 4 ]
1024
+ The schema to apply is the subschema of this resource which contains the
1025
+ matching ` $dynamicAnchor ` . If no matching ` $dynamicAnchor ` is found, see
1026
+ {{failed-refs}}.
1037
1027
1038
- Resolution of ` $dynamicRef ` begins by identifying the outermost schema
1039
- resource in the [ dynamic scope] ( #scopes ) which defines a matching
1040
- ` $dynamicAnchor ` . The schema to apply is the subschema of this resource which
1041
- contains the matching ` $dynamicAnchor ` .
1028
+ [ ^ 4 ] : Because of the nature of dynamic scoping, the target of a dynamic
1029
+ reference may be different depending the instance being evaluated.
1042
1030
1043
- For a full example using these keywords , see {{recursive -example}}.[ ^ 6 ]
1031
+ For a full example using these keyword , see {{dynamic -example}}.[ ^ 6 ]
1044
1032
1045
1033
[ ^ 6 ] : The differences in the hyper-schema meta-schemas from draft-07 and draft
1046
1034
2019-09 dramatically demonstrates the utility of these keywords.
@@ -1205,19 +1193,19 @@ If an implementation has been configured to resolve that identifier to a schema
1205
1193
via pre-loading or other means, it can be used automatically; otherwise, the
1206
1194
behavior described in {{failed-refs}} MUST be used.
1207
1195
1208
- #### JSON Pointer fragments and embedded schema resources {#embedded}
1196
+ #### JSON Pointer IRI fragments and embedded schema resources {#embedded}
1209
1197
1210
1198
Since JSON Pointer IRI fragments are constructed based on the structure of the
1211
1199
schema document, an embedded schema resource and its subschemas can be
1212
- identified by JSON Pointer fragments relative to either its own canonical IRI,
1213
- or relative to any containing resource's IRI.
1200
+ identified by JSON Pointer IRI fragments relative to either its own IRI, or
1201
+ relative to any containing resource's IRI.
1214
1202
1215
1203
Conceptually, a set of linked schema resources should behave identically whether
1216
1204
each resource is a separate document connected with [ schema
1217
1205
references] ( #referenced ) , or is structured as a single document with one or more
1218
1206
schema resources embedded as subschemas.
1219
1207
1220
- Since IRIs involving JSON Pointer fragments relative to the parent schema
1208
+ Since IRIs with JSON Pointer fragments relative to the parent schema
1221
1209
resource's IRI cease to be valid when the embedded schema is moved to a separate
1222
1210
document and referenced, applications and schemas SHOULD NOT use such IRIs to
1223
1211
identify embedded schema resources or locations within them.
@@ -1578,9 +1566,9 @@ subschema, then validation succeeds against this keyword if the instance also
1578
1566
successfully validates against this keyword's subschema.
1579
1567
1580
1568
This keyword has no effect when ` if ` is absent, or when the instance fails to
1581
- validate against the ` if ` subschema. Implementations MUST NOT evaluate the instance
1582
- against this keyword, for either validation or annotation collection purposes,
1583
- in such cases.
1569
+ validate against the ` if ` subschema. Implementations MUST NOT evaluate the
1570
+ instance against this keyword, for either validation or annotation collection
1571
+ purposes, in such cases.
1584
1572
1585
1573
##### ` else `
1586
1574
@@ -1591,8 +1579,8 @@ then validation succeeds against this keyword if the instance successfully
1591
1579
validates against this keyword's subschema.
1592
1580
1593
1581
This keyword has no effect when ` if ` is absent, or when the instance
1594
- successfully validates against the ` if ` subschema. Implementations MUST NOT evaluate
1595
- the instance against this keyword, for either validation or annotation
1582
+ successfully validates against the ` if ` subschema. Implementations MUST NOT
1583
+ evaluate the instance against this keyword, for either validation or annotation
1596
1584
collection purposes, in such cases.
1597
1585
1598
1586
##### ` dependentSchemas ` {#dependent-schemas}
@@ -1856,8 +1844,8 @@ Omitting this keyword has the same assertion behavior as an empty schema.
1856
1844
1857
1845
The value of ` unevaluatedProperties ` MUST be a valid JSON Schema.
1858
1846
1859
- This keyword applies to object instances by applying its subschema to the object's
1860
- property values.
1847
+ This keyword applies to object instances by applying its subschema to the
1848
+ object's property values.
1861
1849
1862
1850
The behavior of this keyword depends on all adjacent keywords as well as
1863
1851
keywords in successfully validated subschemas that apply to the same instance
@@ -1872,9 +1860,9 @@ subschema validates against all applicable property values.
1872
1860
The annotation result of this keyword is the set of instance property names
1873
1861
validated by this keyword's subschema.
1874
1862
1875
- The presence of this keyword affects the behavior of other ` unevaluatedProperties `
1876
- keywords found earlier in the dynamic scope that apply to the same instance
1877
- location.
1863
+ The presence of this keyword affects the behavior of other
1864
+ ` unevaluatedProperties ` keywords found earlier in the dynamic scope that apply
1865
+ to the same instance location.
1878
1866
1879
1867
Omitting this keyword has the same assertion behavior as an empty schema.
1880
1868
@@ -2115,7 +2103,8 @@ determines the canonical nature of the resulting full IRI.[^18]
2115
2103
and direct you to read the CREF located in {{embedded}} for further comments.
2116
2104
2117
2105
While the following IRIs do correctly indicate specific schemas, per the reasons
2118
- outlined in {{embedded}}, they are to be avoided as they may not work in all implementations:
2106
+ outlined in {{embedded}}, they are to be avoided as they may not work in all
2107
+ implementations:
2119
2108
2120
2109
Document location ` /$defs/B ` :
2121
2110
- canonical (and base) ` IRI: https://example.com/other.json `
@@ -2183,7 +2172,7 @@ scope of this specification to determine or provide a set of safe `$ref` removal
2183
2172
transformations, as they depend not only on the schema structure but also on the
2184
2173
intended usage.
2185
2174
2186
- ## %appendix% Example of recursive schema extension {#recursive -example}
2175
+ ## %appendix% Example of recursive schema extension {#dynamic -example}
2187
2176
2188
2177
Consider the following two schemas describing a simple recursive tree structure,
2189
2178
where each node in the tree can have a "data" field of any type. The first
@@ -2235,7 +2224,7 @@ the following full schema IRIs:
2235
2224
- ` https://example.com/strict-tree#node `
2236
2225
2237
2226
In addition, JSON Schema implementations keep track of the fact that these
2238
- fragments were created with ` $dynamicAnchor ` .
2227
+ fragment identifiers were created with ` $dynamicAnchor ` .
2239
2228
2240
2229
If we apply the "strict-tree" schema to the instance, we will follow the ` $ref `
2241
2230
to the "tree" schema, examine its "children" subschema, and find the
@@ -2253,25 +2242,25 @@ At this point, the evaluation path is
2253
2242
1 . ` https://example.com/tree#/properties/children `
2254
2243
1 . ` https://example.com/tree#/properties/children/items `
2255
2244
2256
- Since we are looking for a plain name fragment, which can be defined anywhere
2257
- within a schema resource, the JSON Pointer fragments are irrelevant to this
2258
- check. That means that we can remove those fragments and eliminate consecutive
2259
- duplicates, producing:
2245
+ Since we are looking for a plain name fragment identifier , which can be defined
2246
+ anywhere within a schema resource, the JSON Pointer IRI fragments are irrelevant
2247
+ to this check. That means that we can remove the fragments and eliminate
2248
+ consecutive duplicates, producing:
2260
2249
2261
2250
1 . ` https://example.com/strict-tree `
2262
2251
1 . ` https://example.com/tree `
2263
2252
2264
- In this case, the outermost resource also has a "node" fragment defined by
2265
- ` $dynamicAnchor ` . Therefore instead of resolving the ` $dynamicRef ` to
2253
+ In this case, the outermost resource also has a "node" fragment identifier
2254
+ defined by ` $dynamicAnchor ` . Therefore instead of resolving the ` $dynamicRef ` to
2266
2255
` https://example.com/tree#node ` , we resolve it to
2267
2256
` https://example.com/strict-tree#node ` .
2268
2257
2269
- This way, the recursion in the "tree" schema recurses to the root of
2270
- "strict-tree", instead of only applying "strict-tree" to the instance root, but
2271
- applying "tree" to instance children.
2258
+ The reference in the "tree" schema resolves to the root of "strict-tree", so
2259
+ "strict-tree" is applied not only to the tree instance's root, but also its
2260
+ children.
2272
2261
2273
2262
This example shows both ` $dynamicAnchor ` s in the same place in each schema,
2274
- specifically the resource root schema. Since plain-name fragments are
2263
+ specifically the resource root schema. Since plain-name fragment identifiers are
2275
2264
independent of the JSON structure, this would work just as well if one or both
2276
2265
of the node schema objects were moved under ` $defs ` . It is the matching
2277
2266
` $dynamicAnchor ` values which tell us how to resolve the dynamic reference, not
0 commit comments