diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 7a863a42..f9678ff1 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -645,9 +645,8 @@ Keywords MAY be defined with a partial value, such as a URI-reference, which must be resolved against another value, such as another URI-reference or a full URI, which is found through the lexical - structure of the JSON document. The "$id", "$ref", and - "$dynamicRef" core keywords, and the "base" JSON Hyper-Schema - keyword, are examples of this sort of behavior. + structure of the JSON document. The "$id", and "$ref" core keywords, and the + "base" JSON Hyper-Schema keyword, are examples of this sort of behavior. Note that some keywords, such as "$schema", apply to the lexical @@ -662,18 +661,12 @@ The path from this root schema to any particular keyword (that includes any "$ref" and "$dynamicRef" keywords that may have been resolved) is considered the keyword's "validation path." - - Or should this be the schema object at which processing - begins, even if it is not a root? This has some implications - for the case where "$dynamicAnchor" is only allowed in the - root schema but processing begins in a subschema. - Lexical and dynamic scopes align until a reference keyword is encountered. While following the reference keyword moves processing from one lexical scope into a different one, from the perspective - of dynamic scope, following reference is no different from descending + of dynamic scope, following a reference is no different from descending into a subschema present as a value. A keyword on the far side of that reference that resolves information through the dynamic scope will consider the originating side of the reference to be their @@ -802,9 +795,8 @@ For some by-reference applicators, such as "$ref", the referenced schema can be determined by static analysis of the schema document's lexical scope. Others, - such as "$dynamicRef" (with "$dynamicAnchor"), may make use of dynamic - scoping, and therefore only be resolvable in the process of evaluating - the schema with an instance. + such as "$dynamicRef" (with "$dynamicAnchor"), are only resolvable in the context + of the dynamic scope. @@ -1383,7 +1375,6 @@ The "$anchor" and "$dynamicAnchor" keywords are used to specify such fragments. They are identifier keywords that can only be used to create plain name fragments, rather than absolute URIs as seen with "$id". - The behavior of the created fragment is identical for both keywords. The base URI to which the resulting fragment is appended is the canonical @@ -1393,13 +1384,11 @@ for the document as determined according to RFC 3986. - Separately from the usual usage of URIs, "$dynamicAnchor" - indicates that the fragment is an extension point when used with - the "$dynamicRef" keyword. This low-level, advanced feature - makes it easier to extend recursive schemas such as the meta-schemas, - without imposing any particular semantics on that extension. - See the section on "$dynamicRef" - for details. + In addition to setting an anchor, "$dynamicAnchor" is used to mark locations that + can be used for dynamic scope resolution. This low-level, advanced feature makes + it easier to extend recursive schemas such as the meta-schemas, without imposing + any particular semantics on that extension. See the section on + "$dynamicRef" for details. In most cases, the normal fragment behavior both suffices and @@ -1451,57 +1440,33 @@ The "$ref" keyword is an applicator that is used to reference a statically identified schema. Its results are the results of the referenced schema. - - Note that this definition of how the results are determined means that - other keywords can appear alongside of "$ref" in the same schema object. - - The value of the "$ref" property MUST be a string which is a URI-Reference. + The value of the "$ref" keyword MUST be a string which is a URI-Reference. Resolved against the current URI base, it produces the URI of the schema - to apply. This resolution is safe to perform on schema load, as the - process of evaluating an instance cannot change how the reference resolves. + to apply. This resolution is safe to perform on schema load as neither other + schemas nor the instance can change how the reference resolves.
- The "$dynamicRef" keyword is an applicator that allows for deferring the - full resolution until runtime, at which point it is resolved each time it is - encountered while evaluating an instance. + The "$dynamicRef" keyword is an applicator that is used to reference a + dynamically identified schema. Its results are the results of the referenced + schema. - Together with "$dynamicAnchor", "$dynamicRef" implements a cooperative - extension mechanism that is primarily useful with recursive schemas - (schemas that reference themselves). Both the extension point and the - runtime-determined extension target are defined with "$dynamicAnchor", - and only exhibit runtime dynamic behavior when referenced with - "$dynamicRef". + The URI base used for the "$dynamicRef" keyword is the outermost schema resource + in the dynamic scope that defines an identically + named fragment with "$dynamicAnchor". If no "$dynamicAnchor" is found matching + the fragment in the "$dynamicRef", the URI base is the current lexical scope. - The value of the "$dynamicRef" property MUST be a string which is - a URI-Reference. Resolved against the current URI base, it produces - the URI used as the starting point for runtime resolution. This initial - resolution is safe to perform on schema load. - - - If the initially resolved starting point URI includes a fragment that - was created by the "$dynamicAnchor" keyword, the initial URI MUST be - replaced by the URI (including the fragment) for the outermost schema - resource in the dynamic scope that defines - an identically named fragment with "$dynamicAnchor". - - Requiring both the initial and final URI fragment to be defined - by "$dynamicAnchor" ensures that the more common "$anchor" - never unexpectedly changes the dynamic resolution process - due to a naming conflict across resources. Users of - "$dynamicAnchor" are expected to be aware of the possibility - of such name collisions, while users of "$anchor" are not. - - - - Otherwise, its behavior is identical to "$ref", and no runtime - resolution is needed. + The value of the "$dynamicRef" keyword MUST be a string which is a URI-Reference. + Resolved against the dynamically determined URI base, it produces the URI of the + schema to apply. This resolution is not safe to perform on schema load because + the dynamic scope is not known. It is safe to perform this resolution as part of + a compile step where all schemas involved have been loaded. For a full example using these keyword, see appendix @@ -3580,7 +3545,7 @@ https://example.com/schemas/common#/$defs/count/minimum { "$schema": "https://json-schema.org/draft/2020-11/schema", "$id": "https://example.com/strict-tree", - "$dynamicAnchor": node, + "$dynamicAnchor": "node", "$ref": "tree", "unevaluatedProperties": false @@ -3608,10 +3573,8 @@ https://example.com/schemas/common#/$defs/count/minimum If we apply the "strict-tree" schema to the instance, we will follow the "$ref" to the "tree" schema, examine its "children" subschema, and find the "$dynamicRef": to "#node" (note the "#" for URI fragment syntax) - in its "items" subschema. That reference resolves to - "https://example.com/tree#node", which is a URI with a fragment - created by "$dynamicAnchor". Therefore we must examine the dynamic - scope before following the reference. + in its "items" subschema. We then need to examine the dynamic scope before + following the reference. At this point, the dynamic path is diff --git a/links.json b/links.json index 07ad7a42..fbcbf056 100644 --- a/links.json +++ b/links.json @@ -3,90 +3,83 @@ "$id": "https://json-schema.org/draft/2019-09/links", "title": "Link Description Object", - "allOf": [ - { "required": [ "rel", "href" ] }, - { "$ref": "#/$defs/noRequiredFields" } - ], - "$defs": { - "noRequiredFields": { - "type": "object", - "properties": { - "anchor": { - "type": "string", - "format": "uri-template" - }, - "anchorPointer": { - "type": "string", - "anyOf": [ - { "format": "json-pointer" }, - { "format": "relative-json-pointer" } - ] - }, - "rel": { - "anyOf": [ - { "type": "string" }, - { - "type": "array", - "items": { "type": "string" }, - "minItems": 1 - } - ] - }, - "href": { - "type": "string", - "format": "uri-template" - }, - "hrefSchema": { - "$dynamicRef": "https://json-schema.org/draft/2019-09/hyper-schema#meta", - "default": false - }, - "templatePointers": { - "type": "object", - "additionalProperties": { - "type": "string", - "anyOf": [ - { "format": "json-pointer" }, - { "format": "relative-json-pointer" } - ] - } - }, - "templateRequired": { + "type": "object", + "properties": { + "anchor": { + "type": "string", + "format": "uri-template" + }, + "anchorPointer": { + "type": "string", + "anyOf": [ + { "format": "json-pointer" }, + { "format": "relative-json-pointer" } + ] + }, + "rel": { + "anyOf": [ + { "type": "string" }, + { "type": "array", - "items": { - "type": "string" - }, - "uniqueItems": true - }, - "title": { - "type": "string" - }, - "description": { - "type": "string" - }, - "targetSchema": { - "$dynamicRef": "https://json-schema.org/draft/2019-09/hyper-schema#meta", - "default": true - }, - "targetMediaType": { - "type": "string" - }, - "targetHints": { }, - "headerSchema": { - "$dynamicRef": "https://json-schema.org/draft/2019-09/hyper-schema#meta", - "default": true - }, - "submissionMediaType": { - "type": "string", - "default": "application/json" - }, - "submissionSchema": { - "$dynamicRef": "https://json-schema.org/draft/2019-09/hyper-schema#meta", - "default": true - }, - "$comment": { - "type": "string" + "items": { "type": "string" }, + "minItems": 1 } + ] + }, + "href": { + "type": "string", + "format": "uri-template" + }, + "hrefSchema": { + "$dynamicRef": "#meta", + "default": false + }, + "templatePointers": { + "type": "object", + "additionalProperties": { + "type": "string", + "anyOf": [ + { "format": "json-pointer" }, + { "format": "relative-json-pointer" } + ] } + }, + "templateRequired": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "targetSchema": { + "$dynamicRef": "#meta", + "default": true + }, + "targetMediaType": { + "type": "string" + }, + "targetHints": { }, + "headerSchema": { + "$dynamicRef": "#meta", + "default": true + }, + "submissionMediaType": { + "type": "string", + "default": "application/json" + }, + "submissionSchema": { + "$dynamicRef": "#meta", + "default": true + }, + "$comment": { + "type": "string" } - } + }, + "required": [ "rel", "href" ] }