From eeec848e0a8a81db3733003e58cbf81c5dc4563a Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Thu, 15 Aug 2019 17:51:07 -0700 Subject: [PATCH 01/14] Introduce "schema resource" and canonical URIs This lets us talk more clearly about what an "$id" really is, as will be seen in the next commit. It also introduces the idea of a schema resource having a canonical URI, which is important for explaining why JSON Pointer fragments relative to parent base URIs (meaning that they "cross" a subschema "$id") should have undefined behavior. --- jsonschema-core.xml | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 2d91ffe6..c28e2bb4 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -2,6 +2,7 @@ + @@ -402,10 +403,22 @@ additional keywords that are not part of a formal vocabulary. -
+
+ + A JSON Schema resource is a schema which is + canonically identified by an + absolute URI. + + + As discussed in section + , a JSON Schema document + can contain multiple JSON Schema resources. + The root schema is the schema that comprises the entire JSON document - in question. + in question. The root schema is always a schema resource, where the + URI is determined as described in section + . Some keywords take schemas themselves, allowing JSON Schemas to be nested: @@ -1455,7 +1468,7 @@ to other schemas by specifying their URI. -
+
RFC3986 Section 5.1 defines how to determine the default base URI of a document. @@ -1466,8 +1479,8 @@ situation identifiable by a URI of any known scheme. - If a schema document defines no explicit base URI with "$id" (embedded in content), - the base URI is that determined per + If a schema document defines no explicit base URI with "$id" + (embedded in content), the base URI is that determined per RFC 3986 section 5. @@ -1476,6 +1489,11 @@ RFC 3986 Section 5.1.4. It is RECOMMENDED that implementations document any default base URI that they assume. + + Unless the "$id" keyword described in the next section is present in the + root schema, this base URI SHOULD be considered the canonical URI of the + schema document's root schema resource. +
@@ -3349,6 +3367,7 @@ User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0 + &RFC6596; &RFC7049; &RFC7231; &RFC8288; From a93b605d2f5d72b0de824081567e435782c32ce2 Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Thu, 15 Aug 2019 18:10:52 -0700 Subject: [PATCH 02/14] Canonical URIs and avoiding shadowed JSON Pointers This implements the recent decision to strongly discourage using fragments that cross a base URI change (e.g. an "$id" appearance). This is done by describing schemas identified by absolute URIs as resources (per the literal definition of Univeral Resource Identifier), which was done in the previous commit, and declaring the URI resulting from the "$id" to be the resource's canonical URI. While URIs for subschemas with "$id" and their chidren can be constructed using the base URI from a parent schema, these URIs are non-canonical, and their behavior is undefined. This is on the grounds that switching between embedding and referencing schema resources should behave essentially identically. A difficulty with how annotation collection works in the event of such as switch is noted in a CREF. --- jsonschema-core.xml | 115 +++++++++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 43 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index c28e2bb4..f8e4e562 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -1467,6 +1467,11 @@ identified by URI, and can embed references to other schemas by specifying their URI. + + Several keywords can accept a relative URI-reference, + or a value used to construct a relative URI-reference. For these keywords, + it is necessary to establish a base URI in order to resolve the reference. +
@@ -1498,63 +1503,87 @@
- The "$id" keyword defines a URI for the schema, and the base URI that - other URI references within the schema are resolved against. - A subschema's "$id" is resolved against the base URI of its parent schema. - If no parent schema defines an explicit base URI with "$id", the base URI - is that of the entire document, as determined per - RFC 3986 section 5. + The "$id" keyword identifies a schema resource with its + canonical URI. + + + Note that this URI is an identifier and not necessarily a network locator. + In the case of a network-addressable URL, a schema need not be downloadable + from its canonical URI. If present, the value for this keyword MUST be a string, and MUST represent a - valid URI-reference. - This value SHOULD be normalized, and SHOULD NOT be an empty fragment <#> - or an empty string <>. + valid URI-reference. This URI-reference + SHOULD be normalized, and MUST resolve to an + absolute-URI (without a fragment). + + + This URI also serves as the base URI for relative URI-references in keywords + within the schema resource, in accordance with + RFC 3986 section 5.1.1 regarding base URIs + embedded in content. + + + The presence of "$id" in a subschema indicates that the subschema constitutes + a distinct schema resource within a single schema document. Furthermore, + in accordance with RFC 3986 section 5.1.2 + regarding encapsulating entities, if an "$id" in a subschema is a relative + URI-reference, the base URI for resolving that reference is the URI of + the parent schema resource. + + + If no parent schema object explicitly identifies itself as a resource + with "$id", the base URI is that of the entire document, as established + by the steps given in the previous section.
- The root schema of a JSON Schema document SHOULD contain an "$id" keyword with - an absolute-URI (containing a scheme, but no fragment), - or this absolute URI but with an empty fragment. - + The root schema of a JSON Schema document SHOULD contain an "$id" keyword + with an absolute-URI (containing a scheme, + but no fragment).
-
+
- When an "$id" sets the base URI, the object containing that "$id" and all of - its subschemas can be identified by using a JSON Pointer fragment starting - from that location. This is true even of subschemas that further change the - base URI. Therefore, a single subschema may be accessible by multiple URIs, - each consisting of base URI declared in the subschema or a parent, along with - a JSON Pointer fragment identifying the path from the schema object that - declares the base to the subschema being identified. Examples of this are - shown in section . + Since JSON Pointer URI fragments are constructed based on the structure + of the schema document, an embedded schema resource and its subschemas + can be identified by JSON Pointer fragments relative to either its own + canonical URI, or relative to the containing resource's URI. -
-
- Using JSON Pointer fragments requires knowledge of the structure of the schema. - When writing schema documents with the intention to provide re-usable - schemas, it may be preferable to use a plain name fragment that is not tied to - any particular structural location. This allows a subschema to be relocated - without requiring JSON Pointer references to be updated. + Conceptually, a set of linked schemas should behave identically whether + each schema is a separate document connected with + schema references, or is structured as + a single document with one or more schema resources embedded as + subschemas. + + Note that when using schema references, the reference keyword + appears in the runtime path in the standard output format for + errors and annotations. This means that while the validation + outcome is unchanged when switching between an embedded schema + resource and a referenced one, the runtime paths of annotations + do change. A future draft may allow directly replacing the value + of the reference keyword with its target while leaving the keyword + itself in place in order to make embedding vs referencing transparent + to annotation collection. This would allow replacing + {"$ref": "/foo"} with {"$ref": {"type": "string"}}, assuming + the schema at "verb">"/foo" consists of just a "type" keyword with + value "string". Feedback on this topic is highly encouraged. + - To specify such a subschema identifier, - the "$id" keyword is set to a URI reference with a plain name fragment (not a JSON Pointer fragment). - This value MUST begin with the number sign that specifies a fragment ("#"), - then a letter ([A-Za-z]), - followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), - colons (":"), or periods ("."). + Since URIs involving JSON Pointer fragments relative to the parent + schema resource's URI cease to be valid when the embedded schema + is moved to a separate document and referenced, applications and schemas + SHOULD NOT use such URIs to identify embedded schema resources or + locations within them. The effect of using such URIs is undefined. + Implementations MAY produce an error requiring that the canonical + URI for the embedded resource be used. - The effect of using a fragment in "$id" that isn't blank or doesn't follow the - plain name syntax is undefined. - - How should an "$id" URI reference containing a fragment with other components - be interpreted? There are two cases: when the other components match - the current base URI and when they change the base URI. - + Examples of such URIs with undefined behavior, as well as the appropriate + canonical URIs to use instead, are provided in section + .
@@ -1639,7 +1668,7 @@
-
+
Several keywords can be used to reference a schema which is to be applied to the current instance location. "$ref" and "$recursiveRef" are applicator From 7656e944f0766eb9b03d629caeaae34f3f7234ba Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Thu, 15 Aug 2019 18:13:13 -0700 Subject: [PATCH 03/14] Split $anchor from $id, update examples This adds the $anchor keyword in place of the fragment-only form of $id, and updates the schema identification examples for $anchor and canonical vs non-canonical URIs. --- jsonschema-core.xml | 202 +++++++++++++++++++++++++++++--------------- 1 file changed, 136 insertions(+), 66 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index f8e4e562..9c0476c0 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -1461,7 +1461,7 @@
-
+
To differentiate between schemas in a vast ecosystem, schemas are identified by URI, and can embed references @@ -1586,24 +1586,60 @@ .
-
-
- - Consider the following schema, which shows "$id" being used to identify - the root schema, change the base URI for subschemas, and assign plain - name fragments to subschemas: - - +
+
+ + Using JSON Pointer fragments requires knowledge of the structure of the schema. + When writing schema documents with the intention to provide re-usable + schemas, it may be preferable to use a plain name fragment that is not tied to + any particular structural location. This allows a subschema to be relocated + without requiring JSON Pointer references to be updated. + + + The "$anchor" keyword is used to specify such a fragment. + + + If present, the value of this keyword MUST be a string, which MUST start with + a letter ([A-Za-z]), followed by any number of letters, digits ([0-9]), + hyphens ("-"), underscores ("_"), colons (":"), or periods ("."). + + Note that the anchor string does not include the "#" character, + as it is not a URI-reference. An "$anchor": "foo" becomes the + fragment "#foo" when used in a URI. See below for full examples. + + + + The base URI to which the resulting fragment is appended is determined + by the "$id" keyword as explained in the previous section. + Two "$anchor" keywords in the same schema document MAY have the same + value if they apply to different base URIs, as the resulting full URIs + will be distinct. However, the effect of two "$anchor" keywords with the + same value and the same base URI is undefined. Implementations MAY + raise an error if such usage is detected. + +
+
+
+ + Consider the following schema, which shows "$id" being used to identify + both the root schema and various subschemas, and "$anchor" being used + to define plain name fragment identifiers. + + - -
- - The schemas at the following URI-encoded JSON - Pointers (relative to the root schema) have the following - base URIs, and are identifiable by any listed URI in accordance with - Section above: - - - - - - https://example.com/root.json - https://example.com/root.json# - - - - - https://example.com/root.json#foo - https://example.com/root.json#/$defs/A - - - - - https://example.com/other.json - https://example.com/other.json# - https://example.com/root.json#/$defs/B - - - - - https://example.com/other.json#bar - https://example.com/other.json#/$defs/X - https://example.com/root.json#/$defs/B/$defs/X - - - - - https://example.com/t/inner.json - https://example.com/t/inner.json# - https://example.com/other.json#/$defs/Y - https://example.com/root.json#/$defs/B/$defs/Y - - - - - urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f - urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f# - https://example.com/root.json#/$defs/C - - - - -
+ + + + The schemas at the following URI-encoded JSON + Pointers (relative to the root schema) have the following + base URIs, and are identifiable by any listed URI in accordance with + Section above: + + + + + + + https://example.com/root.json + + + https://example.com/root.json# + + + + + + https://example.com/root.json + + https://example.com/root.json#foo + + + https://example.com/root.json#/$defs/A + + + + + + https://example.com/other.json + + https://example.com/other.json# + + + https://example.com/root.json#/$defs/B + + + + + + https://example.com/other.json + + https://example.com/other.json#bar + + + https://example.com/other.json#/$defs/X + + + https://example.com/root.json#/$defs/B/$defs/X + + + + + + https://example.com/t/inner.json + + https://example.com/t/inner.json#bar + + + https://example.com/t/inner.json# + + + https://example.com/other.json#/$defs/Y + + + https://example.com/root.json#/$defs/B/$defs/Y + + + + + + + urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f + + + urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f# + + + https://example.com/root.json#/$defs/C + + + + +
From bd2b330bff5ef39315e16f937db92e847e7ce43c Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Fri, 16 Aug 2019 00:00:48 -0700 Subject: [PATCH 04/14] Review feedback on canonical $id $id cannot contain a fragment except for an empty one, mostly because a lot of people do that out of habit it seems. This also reworks the wording around non-canonical URIs to avoid an overly broad "undefined behavior." This still doesn't feel ideal but is hopefully an improvement. --- jsonschema-core.xml | 53 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 9c0476c0..b6c3d8e5 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -1515,7 +1515,21 @@ If present, the value for this keyword MUST be a string, and MUST represent a valid URI-reference. This URI-reference SHOULD be normalized, and MUST resolve to an - absolute-URI (without a fragment). + absolute-URI (without a fragment). Therefore, + "$id" MUST NOT contain a non-empty fragment, and SHOULD NOT contain an + empty fragment. + + + Since an empty fragment in the context of the application/schema+json media + type refers to the same resource as the base URI without a fragment, + an implementation MAY normalize a URI ending with an empty fragment by removing + the fragment. However, schema authors SHOULD NOT rely on this behavior + across implementations. + + This is primarily allowed because older meta-schemas have an empty + fragment in their $id (or previously, id). A future draft may outright + forbid even empty fragments in "$id". + This URI also serves as the base URI for relative URI-references in keywords @@ -1543,7 +1557,8 @@ but no fragment).
-
+
Since JSON Pointer URI fragments are constructed based on the structure of the schema document, an embedded schema resource and its subschemas @@ -1576,12 +1591,24 @@ schema resource's URI cease to be valid when the embedded schema is moved to a separate document and referenced, applications and schemas SHOULD NOT use such URIs to identify embedded schema resources or - locations within them. The effect of using such URIs is undefined. - Implementations MAY produce an error requiring that the canonical - URI for the embedded resource be used. + locations within them. + + + Using such URIs is unreliable, and an implementation MAY choose not to + support them. If an embedded schema were to be replaced with a reference, + then the JSON Pointer fragment URI for that schema relative to its + parent's base URI would then identify the reference, while JSON Pointers + to locations within the formerly embedded resource would become invalid. + + If the change regarding reference replacement noted in the previous + CREF were to be implemented, the pointer behavior would be more + consistent. Really it is the pointers to deeper locations within + embedded schemas which should be strongly discouraged and + need not be supported. + - Examples of such URIs with undefined behavior, as well as the appropriate + Examples of such non-canonical URIs, as well as the appropriate canonical URIs to use instead, are provided in section . @@ -1654,7 +1681,9 @@ The schemas at the following URI-encoded JSON Pointers (relative to the root schema) have the following base URIs, and are identifiable by any listed URI in accordance with - Section above: + sections and + above. As previously + noted, support for non-canonical URIs is OPTIONAL. @@ -1685,7 +1714,7 @@ https://example.com/other.json# - + https://example.com/root.json#/$defs/B @@ -1699,7 +1728,7 @@ https://example.com/other.json#/$defs/X - + https://example.com/root.json#/$defs/B/$defs/X @@ -1713,10 +1742,10 @@ https://example.com/t/inner.json# - + https://example.com/other.json#/$defs/Y - + https://example.com/root.json#/$defs/B/$defs/Y @@ -1729,7 +1758,7 @@ urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f# - + https://example.com/root.json#/$defs/C From 4f110e769c6a264dc794ed87d44ac59287c7cc2a Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Thu, 15 Aug 2019 23:05:40 -0700 Subject: [PATCH 05/14] Add $anchor to meta-schema, update $id --- hyper-schema.json | 2 +- links.json | 2 +- meta/core.json | 8 +++++++- schema.json | 4 ++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/hyper-schema.json b/hyper-schema.json index bc5ba60d..54728855 100644 --- a/hyper-schema.json +++ b/hyper-schema.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/hyper-schema#", + "$schema": "https://json-schema.org/draft/2019-08/hyper-schema", "$id": "https://json-schema.org/draft/2019-08/hyper-schema", "$vocabulary": { "https://json-schema.org/draft/2019-08/vocab/core": true, diff --git a/links.json b/links.json index 0e0110db..51aeb18b 100644 --- a/links.json +++ b/links.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/hyper-schema#", + "$schema": "https://json-schema.org/draft/2019-08/hyper-schema", "$id": "https://json-schema.org/draft/2019-08/links", "title": "Link Description Object", "allOf": [ diff --git a/meta/core.json b/meta/core.json index 9dd8fbc2..73e09a85 100644 --- a/meta/core.json +++ b/meta/core.json @@ -11,12 +11,18 @@ "properties": { "$id": { "type": "string", - "format": "uri-reference" + "format": "uri-reference", + "$comment": "Non-empty fragments not allowed.", + "pattern": "^[^#]#?$" }, "$schema": { "type": "string", "format": "uri" }, + "$anchor": { + "type": "string", + "pattern": "^[A-Za-z][-A-Za-z0-9.:_]*$" + }, "$ref": { "type": "string", "format": "uri-reference" diff --git a/schema.json b/schema.json index daca1a49..80c73c70 100644 --- a/schema.json +++ b/schema.json @@ -1,6 +1,6 @@ { - "$schema": "https://json-schema.org/draft/2019-08/schema#", - "$id": "https://json-schema.org/draft/2019-08/schema#", + "$schema": "https://json-schema.org/draft/2019-08/schema", + "$id": "https://json-schema.org/draft/2019-08/schema", "$vocabulary": { "https://json-schema.org/draft/2019-08/vocab/core": true, "https://json-schema.org/draft/2019-08/vocab/applicator": true, From e1e3441bea7c7d33e8bab4dbc73d63d30b5f65a2 Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Thu, 15 Aug 2019 23:04:50 -0700 Subject: [PATCH 06/14] Fix more examples for $anchor and canonical $id --- jsonschema-core.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index b6c3d8e5..504e0df5 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -2104,7 +2104,7 @@ }, "$defs": { "single": { - "$id": "#item", + "$anchor": "item", "type": "object", "additionalProperties": { "$ref": "other.json" } } @@ -2892,8 +2892,8 @@ https://json-schema.org/draft/2019-08/schema#/$defs/nonNegativeInteger/minimum Date: Thu, 15 Aug 2019 23:06:16 -0700 Subject: [PATCH 07/14] Changelog for $id and $anchor --- jsonschema-core.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 504e0df5..01a3aad3 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -3579,6 +3579,9 @@ User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0 Additional guidance on initial base URIs beyond network retrieval Allow "schema" media type parameter for "application/schema+json" Better explanation of media type parameters and the HTTP Accept header + Use "$id" to establish canonical and base absolute-URIs only, no fragments + Replace plain-name-fragment-only form of $id with $anchor + Clarified that the behavior of JSON Pointers across $id boundary is unreliable From 428be3ccaef4f641fc2cd0465f6eff77cf13c1d4 Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Sat, 17 Aug 2019 20:53:13 -0700 Subject: [PATCH 08/14] Missed a xref change to $anchor --- jsonschema-core.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 01a3aad3..e292e275 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -479,7 +479,7 @@ Defining and referencing a plain name fragment identifier within an "application/schema+json" document are specified - in the "$id" keyword section. + in the "$anchor" keyword section. From 472ed6bf4701204c2a478e651526f243b2862f48 Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Mon, 19 Aug 2019 22:06:03 -0700 Subject: [PATCH 09/14] Refer to the "default" meta-schema Now that the core spec explicitly defines this as the default, let's call it that. Because calling it the "core and validation" meta-schema is annoying. --- jsonschema-validation.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsonschema-validation.xml b/jsonschema-validation.xml index f0881992..432d2bc9 100644 --- a/jsonschema-validation.xml +++ b/jsonschema-validation.xml @@ -176,8 +176,8 @@
- The current URI for the JSON Schema Validation meta-schema is - . + The current URI for the default JSON Schema meta-schema is + . For schema author convenience, this meta-schema describes all vocabularies defined in this specification and the JSON Schema Core specification, as well as two former keywords which are reserved for a transitional period. From 2da139a0df4c513cc419eb5480184458cf201fdf Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Mon, 19 Aug 2019 22:16:53 -0700 Subject: [PATCH 10/14] Dont use # in $schema values Since we're now very strongly discouraging fragments in $id, let's not use them in $schema either. It works either way, but I like the consistency. Stylistically, referring to "#" internally makes sense, while using an absolute-URI per RFC 3986 (no fragment) makes sense externally. --- jsonschema-hyperschema.xml | 12 ++++++------ meta/applicator.json | 2 +- meta/content.json | 2 +- meta/core.json | 2 +- meta/format.json | 2 +- meta/hyper-schema.json | 2 +- meta/meta-data.json | 2 +- meta/validation.json | 2 +- output/hyper-schema.json | 2 +- output/schema.json | 2 +- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/jsonschema-hyperschema.xml b/jsonschema-hyperschema.xml index e3ddf254..94b3ecfe 100644 --- a/jsonschema-hyperschema.xml +++ b/jsonschema-hyperschema.xml @@ -1618,7 +1618,7 @@ Link: ; rel="describedBy" ; rel="describedBy" ; rel="describedBy" ; rev="up" ; rev="up" ; rev="up" Date: Sat, 24 Aug 2019 00:15:24 -0700 Subject: [PATCH 11/14] More consistent concept of schema resources This further clarifies the schema resource concept and how it is used. It provides an example to simplify the explanation of how non-canonical URIs can be problematic. This also relaxes a restriction on "$schema" that has no functional impact but avoids requiring implementations to detect and handle a rather complex case (embedding schema resources with different "$schema" values). And also means that embedding can work without having to change the embedded value by removing the "$schema" keyword. Additional best practices for embedding will follow in a separate commit. --- jsonschema-core.xml | 134 +++++++++++++++++++++++++++++++------------- 1 file changed, 94 insertions(+), 40 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index e292e275..7ba27e8c 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -409,11 +409,6 @@ canonically identified by an absolute URI. - - As discussed in section - , a JSON Schema document - can contain multiple JSON Schema resources. - The root schema is the schema that comprises the entire JSON document in question. The root schema is always a schema resource, where the @@ -442,6 +437,15 @@ As with the root schema, a subschema is either an object or a boolean. + + As discussed in section + , a JSON Schema document + can contain multiple JSON Schema resources. When used without qualification, + the term "root schema" refers to the document's root schema. In some + cases, resource root schemas are discussed. A resource's root schema + is its top-level schema object, which would also be a document root schema + if the resource were to be extracted to a standalone JSON Schema document. +
@@ -624,7 +628,7 @@ Note that some keywords, such as "$schema", apply to the lexical scope of the entire schema document, and therefore MUST only - appear in the document's root schema. + appear in a schema resource's root schema. Other keywords may take into account the dynamic scope that @@ -1131,11 +1135,15 @@ media type "application/schema+json". - The "$schema" keyword SHOULD be used in a root schema. - It MUST NOT appear in subschemas. If absent from the root schema, the + The "$schema" keyword SHOULD be used in a resource root schema. + It MUST NOT appear in resource subschemas. If absent from the root schema, the resulting behavior is implementation-defined. + If multiple schema resources are present in a single document, then all + schema resources SHOULD Have the same value for "$schema". The result of + differing values for "$schema" within the same schema document is + implementation-defined. Using multiple "$schema" keywords in the same document would imply that the feature set and therefore behavior can change within a document. This would @@ -1145,6 +1153,12 @@ implementation behavior is subject to be revised or liberalized in future drafts. + + The exception made for embedded schema resources is to + allow bundling multiple schema resources into a single schema document + without needing to change their contents, as described later in this + specification. +