@@ -240,7 +240,7 @@ A schema that itself describes a schema is called a meta-schema. Meta-schemas
240240are used to validate JSON Schemas and specify the set of keywords those schemas
241241are using.
242242
243- #### Root Schema and Subschemas and Resources {#root}
243+ #### Root Schema, Subschemas, and Resources {#root}
244244
245245A JSON Schema resource is a schema which is
246246[ canonically] ( https://www.rfc-editor.org/info/rfc6596 ) identified by an
@@ -334,9 +334,8 @@ NCNameChar = NCNameStartChar / "-" / "." / DIGIT
334334All fragment identifiers that do not match the JSON Pointer syntax MUST be
335335interpreted as plain name fragment identifiers.
336336
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.
340339
341340## General Considerations
342341
@@ -950,40 +949,35 @@ an [absolute IRI](https://www.rfc-editor.org/rfc/rfc3987.html#section-2.2)
950949
951950#### Defining location-independent identifiers {#anchors}
952951
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.
952+ Using JSON Pointers in IRI fragments to reference subschemas couples the IRI to
953+ the structure of the schema. Using plain name fragment identifiers in IRI
954+ fragments to identify subschemas is sometimes preferable because it is not tied
955+ to a particular structural location. This allows a subschema to be relocated
956+ without requiring references to be updated.
976957
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 ` .
958+ The ` $anchor ` and ` $dynamicAnchor ` keywords are used to define
959+ location-independent identifiers for subschemas within a schema resource.
980960
981- If present, the value of these keywords MUST be a string and MUST conform to the
982- plain name fragment identifier syntax defined in {{fragments}}.[ ^ 4 ]
961+ ` $anchor ` defines a plain name fragment identifier that can be used in IRI
962+ fragments as an alternative to JSON Pointers. [ ^ 4 ] See {{fragments}}.
983963
984964[ ^ 4 ] : Note that the anchor string does not include the "#" character, as it is
985- not a IRI reference. An ` $anchor ` : "foo" becomes the fragment ` #foo ` when used
986- in a IRI. See below for full examples.
965+ just a fragment identifier not an IRI reference. To reference the "foo"
966+ ` $anchor ` from the same schema resource, you would use the fragment-only IRI
967+ ` #foo ` . See below for full examples.
968+
969+ ` $dynamicAnchor ` defines a different kind of fragment identifier that only has
970+ meaning when used with ` $dynamicRef ` . It's not a normal fragment identifier and
971+ therefore can't be used anywhere other than ` $dynamicRef ` . Normal [ fragment
972+ identifiers] ( https://www.rfc-editor.org/rfc/rfc3986#section-3.5 ) identify the
973+ secondary resource (the subschema) while the rest of the IRI identifies the
974+ primary resource (the schema resource). The fragment identifiers defined by
975+ ` $dynamicAnchor ` are not normal fragment identifies because they identify both
976+ the primary resource and the secondary resource. See {{dynamic-ref}} for
977+ details.
978+
979+ If present, the value of these keywords MUST be a string and MUST conform to the
980+ plain name fragment identifier syntax defined in {{fragments}}.
987981
988982#### Duplicate schema identifiers {#duplicate-iris}
989983
@@ -1007,7 +1001,7 @@ identified schema. Its results are the results of the referenced schema.[^5]
10071001[ ^ 5 ] : Note that this definition of how the results are determined means that
10081002other keywords can appear alongside of ` $ref ` in the same schema object.
10091003
1010- The value of the ` $ref ` keyword MUST be a string which is a IRI reference.
1004+ The value of the ` $ref ` keyword MUST be a string which is an IRI reference.
10111005Resolved against the current IRI base, it produces the IRI of the schema to
10121006apply. This resolution is safe to perform on schema load, as the process of
10131007evaluating an instance cannot change how the reference resolves.
@@ -1019,28 +1013,25 @@ default to operating offline.
10191013
10201014##### Dynamic References with ` $dynamicRef ` {#dynamic-ref}
10211015
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.
1016+ The ` $dynamicRef ` keyword is an applicator that is used when the referencing
1017+ schema might need to override where a reference in the referenced schema will
1018+ resolve. This is useful for cases such as authoring a recursive schema that can
1019+ be extended or a generic schema such as a list whose items are defined by the
1020+ referencing schema.
10301021
10311022The value of the ` $dynamicRef ` property MUST be formatted as a valid
1032- [ IRI plain name fragment] ( #fragments ) .[ ^ 3 ]
1023+ [ fragment-only IRI ] ( #fragments ) .[ ^ 3 ]
10331024
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 ` .
1025+ [ ^ 3 ] : ` $dynamicAnchor ` defines the anchor with plain text, e.g. ` foo ` . Although,
1026+ for historical reasons, the value of ` $dynamicRef ` still uses a fragment-only
1027+ IRI syntax, e.g. ` #foo ` .
10371028
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 ` .
1029+ Resolution of ` $dynamicRef ` begins by identifying the outermost schema resource
1030+ in the [ dynamic scope] ( #scopes ) which defines a matching ` $dynamicAnchor ` . The
1031+ schema to apply is the subschema of this resource which contains the matching
1032+ ` $dynamicAnchor ` . If no matching ` $dynamicAnchor ` is found, see {{failed-refs}} .
10421033
1043- For a full example using these keywords, see {{recursive -example}}.[ ^ 6 ]
1034+ For a full example using these keywords, see {{dynamic -example}}.[ ^ 6 ]
10441035
10451036[ ^ 6 ] : The differences in the hyper-schema meta-schemas from draft-07 and draft
104610372019-09 dramatically demonstrates the utility of these keywords.
@@ -1205,22 +1196,23 @@ If an implementation has been configured to resolve that identifier to a schema
12051196via pre-loading or other means, it can be used automatically; otherwise, the
12061197behavior described in {{failed-refs}} MUST be used.
12071198
1208- #### JSON Pointer fragments and embedded schema resources {#embedded}
1199+ #### JSON Pointer fragment identifiers and embedded schema resources {#embedded}
12091200
1210- Since JSON Pointer IRI fragments are constructed based on the structure of the
1211- 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.
1201+ Since JSON Pointer fragment identifiers are based on the structure of the schema
1202+ document, an embedded schema resource and its subschemas can be identified using
1203+ JSON Pointer IRI fragments relative to either its own IRI, or relative to any
1204+ containing resource's IRI.
12141205
12151206Conceptually, a set of linked schema resources should behave identically whether
12161207each resource is a separate document connected with [ schema
12171208references] ( #referenced ) , or is structured as a single document with one or more
12181209schema resources embedded as subschemas.
12191210
1220- Since IRIs involving JSON Pointer fragments relative to the parent schema
1221- resource's IRI cease to be valid when the embedded schema is moved to a separate
1222- document and referenced, applications and schemas SHOULD NOT use such IRIs to
1223- identify embedded schema resources or locations within them.
1211+ Since IRIs with JSON Pointer fragments are relative to the parent schema
1212+ resource's IRI, they cease to be valid when the embedded schema is moved to a
1213+ separate document and referenced. Because of this, applications and schemas
1214+ SHOULD NOT use such IRIs to identify embedded schema resources or locations
1215+ within them.
12241216
12251217Consider the following schema document that contains another schema resource
12261218embedded within it:
@@ -1244,7 +1236,7 @@ For the `additionalProperties` schema within that embedded resource, the IRI
12441236object, but that object's IRI relative to its resource's canonical IRI is
12451237` https://example.com/bar#/additionalProperties ` .
12461238
1247- Now consider the following two schema resources linked by reference using a IRI
1239+ Now consider the following two schema resources linked by reference using an IRI
12481240value for ` $ref ` :
12491241
12501242``` jsonschema
@@ -1264,10 +1256,11 @@ value for `$ref`:
12641256```
12651257
12661258Here we see that ` https://example.com/bar#/additionalProperties ` , using a JSON
1267- Pointer fragment appended to the canonical IRI of the "bar" schema resource, is
1268- still valid, while ` https://example.com/foo#/items/additionalProperties ` , which
1269- relied on a JSON Pointer fragment appended to the canonical IRI of the "foo"
1270- schema resource, no longer resolves to anything.
1259+ Pointer fragment identifier appended to the canonical IRI of the "bar" schema
1260+ resource, is still valid, while
1261+ ` https://example.com/foo#/items/additionalProperties ` , which relied on a JSON
1262+ Pointer fragment identifier appended to the canonical IRI of the "foo" schema
1263+ resource, no longer resolves to anything.
12711264
12721265Note also that ` https://example.com/foo#/items ` is valid in both arrangements,
12731266but resolves to a different value. This IRI ends up functioning similarly to a
@@ -1282,14 +1275,15 @@ undefined. Schema authors SHOULD NOT rely on such IRIs, as using them may
12821275reduce interoperability.[ ^ 8 ]
12831276
12841277[ ^ 8 ] : This is to avoid requiring implementations to keep track of a whole stack
1285- of possible base IRIs and JSON Pointer fragments for each, given that all but
1286- one will be fragile if the schema resources are reorganized. Some have argued
1287- that this is easy so there is no point in forbidding it, while others have
1288- argued that it complicates schema identification and should be forbidden.
1289- Feedback on this topic is encouraged. After some discussion, we feel that we
1290- need to remove the use of "canonical" in favour of talking about JSON Pointers
1291- which reference across schema resource boundaries as undefined or even forbidden
1292- behavior (< https://github.com/json-schema-org/json-schema-spec/issues/937 > ,
1278+ of possible base IRIs and JSON Pointer fragment identifiers for each, given
1279+ that all but one will be fragile if the schema resources are reorganized. Some
1280+ have argued that this is easy so there is no point in forbidding it, while
1281+ others have argued that it complicates schema identification and should be
1282+ forbidden. Feedback on this topic is encouraged. After some discussion, we feel
1283+ that we need to remove the use of "canonical" in favour of talking about JSON
1284+ Pointers which reference across schema resource boundaries as undefined or even
1285+ forbidden behavior
1286+ (< https://github.com/json-schema-org/json-schema-spec/issues/937 > ,
12931287< https://github.com/json-schema-org/json-schema-spec/issues/1183 > )
12941288
12951289Further examples of such non-canonical IRI construction, as well as the
@@ -1578,9 +1572,9 @@ subschema, then validation succeeds against this keyword if the instance also
15781572successfully validates against this keyword's subschema.
15791573
15801574This 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.
1575+ validate against the ` if ` subschema. Implementations MUST NOT evaluate the
1576+ instance against this keyword, for either validation or annotation collection
1577+ purposes, in such cases.
15841578
15851579##### ` else `
15861580
@@ -1591,8 +1585,8 @@ then validation succeeds against this keyword if the instance successfully
15911585validates against this keyword's subschema.
15921586
15931587This 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
1588+ successfully validates against the ` if ` subschema. Implementations MUST NOT
1589+ evaluate the instance against this keyword, for either validation or annotation
15961590collection purposes, in such cases.
15971591
15981592##### ` dependentSchemas ` {#dependent-schemas}
@@ -1856,8 +1850,8 @@ Omitting this keyword has the same assertion behavior as an empty schema.
18561850
18571851The value of ` unevaluatedProperties ` MUST be a valid JSON Schema.
18581852
1859- This keyword applies to object instances by applying its subschema to the object's
1860- property values.
1853+ This keyword applies to object instances by applying its subschema to the
1854+ object's property values.
18611855
18621856The behavior of this keyword depends on all adjacent keywords as well as
18631857keywords in successfully validated subschemas that apply to the same instance
@@ -1872,9 +1866,9 @@ subschema validates against all applicable property values.
18721866The annotation result of this keyword is the set of instance property names
18731867validated by this keyword's subschema.
18741868
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.
1869+ The presence of this keyword affects the behavior of other
1870+ ` unevaluatedProperties ` keywords found earlier in the dynamic scope that apply
1871+ to the same instance location.
18781872
18791873Omitting this keyword has the same assertion behavior as an empty schema.
18801874
@@ -2115,7 +2109,8 @@ determines the canonical nature of the resulting full IRI.[^18]
21152109and direct you to read the CREF located in {{embedded}} for further comments.
21162110
21172111While 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:
2112+ outlined in {{embedded}}, they are to be avoided as they may not work in all
2113+ implementations:
21192114
21202115Document location ` /$defs/B ` :
21212116- canonical (and base) ` IRI: https://example.com/other.json `
@@ -2183,7 +2178,7 @@ scope of this specification to determine or provide a set of safe `$ref` removal
21832178transformations, as they depend not only on the schema structure but also on the
21842179intended usage.
21852180
2186- ## %appendix% Example of recursive schema extension {#recursive -example}
2181+ ## %appendix% Example of recursive schema extension {#dynamic -example}
21872182
21882183Consider the following two schemas describing a simple recursive tree structure,
21892184where each node in the tree can have a "data" field of any type. The first
@@ -2235,7 +2230,7 @@ the following full schema IRIs:
22352230- ` https://example.com/strict-tree#node `
22362231
22372232In addition, JSON Schema implementations keep track of the fact that these
2238- fragments were created with ` $dynamicAnchor ` .
2233+ fragment identifiers were created with ` $dynamicAnchor ` .
22392234
22402235If we apply the "strict-tree" schema to the instance, we will follow the ` $ref `
22412236to the "tree" schema, examine its "children" subschema, and find the
@@ -2253,25 +2248,25 @@ At this point, the evaluation path is
225322481 . ` https://example.com/tree#/properties/children `
225422491 . ` https://example.com/tree#/properties/children/items `
22552250
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:
2251+ Since we are looking for a plain name fragment identifier , which can be defined
2252+ anywhere within a schema resource, the JSON Pointer IRI fragments are irrelevant
2253+ to this check. That means that we can remove the fragments and eliminate
2254+ consecutive duplicates, producing:
22602255
226122561 . ` https://example.com/strict-tree `
226222571 . ` https://example.com/tree `
22632258
2264- In this case, the outermost resource also has a "node" fragment defined by
2265- ` $dynamicAnchor ` . Therefore instead of resolving the ` $dynamicRef ` to
2259+ In this case, the outermost resource also has a "node" fragment identifier
2260+ defined by ` $dynamicAnchor ` . Therefore instead of resolving the ` $dynamicRef ` to
22662261` https://example.com/tree#node ` , we resolve it to
22672262` https://example.com/strict-tree#node ` .
22682263
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.
2264+ The reference in the "tree" schema resolves to the root of "strict-tree", so
2265+ "strict-tree" is applied not only to the tree instance's root, but also its
2266+ children.
22722267
22732268This example shows both ` $dynamicAnchor ` s in the same place in each schema,
2274- specifically the resource root schema. Since plain-name fragments are
2269+ specifically the resource root schema. Since plain-name fragment identifiers are
22752270independent of the JSON structure, this would work just as well if one or both
22762271of the node schema objects were moved under ` $defs ` . It is the matching
22772272` $dynamicAnchor ` values which tell us how to resolve the dynamic reference, not
0 commit comments