diff --git a/jsonschema-core.xml b/jsonschema-core.xml index e5067e0c..a8ddb9d5 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -41,13 +41,25 @@ - + Wellcome Sanger Institute
bh7@sanger.ac.uk
+ +
+ + + Auckland + + NZ + + gregsdennis@yahoo.com +
+
+ Internet Engineering Task Force JSON @@ -93,7 +105,8 @@ This specification defines JSON Schema core terminology and mechanisms, including pointing to another JSON Schema by reference, dereferencing a JSON Schema reference, - and specifying the vocabulary being used. + specifying the vocabulary being used, + and defining the expected output. Other specifications define the vocabularies that perform assertions about validation, @@ -610,6 +623,9 @@ exists during the evaluation of a schema, typically together with an instance document. The outermost dynamic scope is the root schema of the schema document in which processing begins. + The path from this root schema to any particular keyword (that + includes any "$ref" and "$recursiveRef" 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 @@ -628,8 +644,8 @@ dynamic parent, rather than examining the local lexically enclosing parent. - The concept of dynamic scope is primarily used with "$recursiveRef" - and "$recursiveAnchor", and should be considered and advanced feature + The concept of dynamic scope is primarily used with "$recursiveRef", + "$recursiveAnchor", and should be considered an advanced feature and used with caution when defining additional keywords. @@ -1683,14 +1699,6 @@
- - - The exact structure and format of the information collected is TBD, - but will be defined before the next draft. Some details of this - section may change as a result, but the overall process is expected - to remain the same. See GitHub issue #396 to track progress. - - Annotations are collected by keywords that explicitly define annotation-collecting behavior. Note that boolean schemas cannot @@ -1706,12 +1714,13 @@ The instance location to which it is attached, as a JSON Pointer - The absolute schema location of the attaching keyword, as a URI + The schema location path, indicating how reference keywords + such as "$ref" were followed to reach the absolute schema location. - The schema location path, indicating how reference keywords - such as "$ref" were followed to reach the absolute schema location - The exact format of this path is TBD, again see issue #396 + The absolute schema location of the attaching keyword, as a URI. + This MAY be omitted if it is the same as the schema location path + from above. The attached value(s) @@ -2379,6 +2388,454 @@
+
+ + JSON Schema is defined to be platform-independent. As such, to increase compatibility + across platforms, implementations SHOULD conform to a standard validation output + format. This section describes the minimum requirements that consumers will need to + properly interpret validation results. + + +
+ + JSON Schema output is defined using the JSON Schema data instance model as described + in section 4.2.1. Implementations MAY deviate from this as supported by their + specific languages and platforms, however it is RECOMMENDED that the output be + convertible to the JSON format defined herein via serialization or other means. + +
+ +
+ + This specification defines four output formats. See the "Output Structure" + section for the requirements of each format. + + + Flag - A boolean which simply indicates the overall validation result + with no further details. + + + Basic - Provides validation information in a flat list structure. + + + Detailed - Provides validation information in a condensed hierarchical + structure based on the structure of the schema. + + + Verbose - Provides validation information in an uncondensed hierarchical + structure that matches the exact structure of the schema. + + + An implementation SHOULD provide at least the "flag", "basic", or "detailed" + format and MAY provide the "verbose" format. If it provides one or more of the + complex formats, it MUST also provide the "flag" format. Implementations SHOULD + specify in their documentation which formats they support. + + +
+ +
+ + Beyond the simplistic "flag" output, additional information is useful to aid in + debugging a schema or instance. Each sub-result SHOULD contain the information + contained within this section at a minimum. + + + A single object that contains all of these components is considered an + output unit. + + + Implementations MAY elect to provide additional information. + + +
+ + The relative location of the validating keyword that follows the validation + path. The value MUST be expressed as a JSON Pointer, and it MUST include + any by-reference applicators such as "$ref" or "$recursiveRef". + +
+ + + +
+ + Note that this pointer may not be resolvable due to the inclusion of these + applicator keywords. + + + The JSON key for this information is "keywordLocation". + +
+ +
+ + The absolute, dereferenced location of the validating keyword. The value MUST + be expressed as an absolute URI, and it MUST NOT include by-reference applicators + such as "$ref" or "$recursiveRef". + +
+ + + +
+ + This information MAY be omitted only if either the relative location contains + no references or if the schema does not declare an absolute URI as its "$id". + + + The JSON key for this information is "absoluteKeywordLocation". + +
+ +
+ + The location of the JSON value within the instance being validated. The + value MUST be expressed as a JSON Pointer. + + + The JSON key for this information is "instanceLocation". + +
+ +
+ + The error or annotation that is produced by the validation. + + + For errors, the specific wording for the message is not defined by this + specification. Implementations will need to provide this. + + + The JSON key for failed validations is "error"; for successful validations + it is "annotation". + +
+ +
+ + For the two hierarchical structures, this property will hold nested errors + and annotations. + + + The JSON key for nested results in failed validations is "errors"; for + successful validations it is "annotations". + +
+ +
+ +
+ + The output MUST be an object containing a boolean property named "valid". When + additional information about the result is required, the output MUST also contain + "errors" or "annotations" as described below. + + + "valid" - a boolean value indicating the overall validation success or + failure + + + "errors" - the collection of errors or annotations produced by a failed + validation + + + "annotations" - the collection of errors or annotations produced by a + successful validation + + + For these examples, the following schema and instance will be used. + +
+ + + +
+ + This instance will fail validation and produce errors, but it's trivial to deduce + examples for passing schemas that produce annotations. + + + Specifically, the errors it will produce are: + + + The second element in the "vertices" property is missing a "y" property. + + + The second element in the "vertices" property has a disallowed "z" property. + + + There are only two vertices, but three are required. + + + Note that neither the error message property nor its wording as depicted in these + examples is not a requirement of this specification. Implementations SHOULD craft + error messages tailored for their audience. + + +
+ + In the simplest case, merely the boolean result for the "valid" valid property + needs to be fulfilled. + +
+ + + +
+ + Because no errors or annotations are returned with this format, it is + RECOMMENDED that implementations use short-circuiting logic to return + failure or success as soon as the outcome can be determined. For example, + if an "anyOf" keyword contains five sub-schemas, and the second one + passes, there is no need to check the other three. The logic can simply + return with success. + +
+ +
+ + The "Basic" structure is a flat list of output units. + +
+ + + +
+
+ +
+ + The "Detailed" structure is based on the schema and can be more readable + for both humans and machines. Having the structure organized this way makes + associations between the errors more apparent. For example, the fact that + the missing "y" property and the extra "z" property both stem from the same + location in the instance is not immediately obvious in the "Basic" structure. + In a hierarchy, the correllation is more easily identified. + + + The following rules govern the construction of the results object: + + + All applicator keywords ("*Of", "$ref", "if"/"then"/"else", etc.) require + a node. + + + Nodes that have no children are removed. + + + Nodes that have a single child are replaced by the child. + + + Branch nodes do not require an error message or an annotation. + +
+ + + +
+
+ +
+ + The "Verbose" structure is a fully realized hierarchy that exactly matches + that of the schema. This structure has applications in form generation and + validation where the error's location is important. + + + The primary difference between this and the "Detailed" structure is that + all results are returned. This includes sub-schema validation results that + would otherwise be removed (e.g. annotations for failed validations, + successful validations inside a `not` keyword, etc.). Because of this, it + is RECOMMENDED that each node also carry a `valid` property to indicate the + validation result for that node. + + + Because this output structure can be quite large, a smaller example is given + here for brevity. The full output structure of the example above can be found + here. + +
+ + + +
+
+ +
+ + For convenience, a JSON Schema has been provided to validate output generated + by implementations. It can be found here. + +
+ +
+ +
+
diff --git a/schema-output.json b/schema-output.json new file mode 100644 index 00000000..579ef8bb --- /dev/null +++ b/schema-output.json @@ -0,0 +1,85 @@ +{ + "$schema": "http://json-schema.org/draft-08/schema#", + "$id": "http://json-schema.org/draft-08/schema-output#", + "description": "A schema that validates the minimum requirements for validation output", + "$defs": { + "outputUnit":{ + "properties": { + "valid": { "type": "boolean" }, + "keywordLocation": { + "type": "string", + "format": "uri-reference" + }, + "absoluteKeywordLocation": { + "type": "string", + "format": "uri" + }, + "instanceLocation": { + "type": "string", + "format": "uri-reference" + }, + "errors": { + "$ref": "#/$defs/outputUnitArray" + }, + "annotations": { + "$ref": "#/$defs/outputUnitArray" + } + }, + "required": [ "valid", "keywordLocation", "instanceLocation" ], + "allOf": [ + { + "if": { + "properties": { + "valid": { "const": false } + } + }, + "then": { + "required": [ "errors" ] + } + }, + { + "if": { + "oneOf": [ + { + "properties": { + "keywordLocation": { + "pattern": ".*/$ref/.*" + } + } + }, + { + "properties": { + "keywordLocation": { + "pattern": ".*/$recursiveRef/.*" + } + } + } + ] + }, + "then": { + "required": [ "absoluteKeywordLocation" ] + } + } + ] + }, + "outputUnitArray": { + "type": "array", + "items": { "$ref": "#/$defs/outputUnit" } + }, + "flag": { + "properties": { + "valid": { "type": "boolean" } + }, + "required": [ "valid" ] + }, + "basic": { "$ref": "#/outputUnit" }, + "detailed": { "$ref": "#/outputUnit" }, + "verbose": { "$ref": "#/outputUnit" } + }, + "oneOf": [ + { "$ref": "#/$defs/flag" }, + { "$ref": "#/$defs/basic" }, + { "$ref": "#/$defs/detailed" }, + { "$ref": "#/$defs/verbose" } + ] +} \ No newline at end of file diff --git a/standardized-output-verbose.json b/standardized-output-verbose.json new file mode 100644 index 00000000..ef50444f --- /dev/null +++ b/standardized-output-verbose.json @@ -0,0 +1,130 @@ +{ + "valid": false, + "keywordLocation": "#", + "instanceLocation": "#", + "errors": [ + { + "valid": true, + "keywordLocation": "#/definitions", + "instanceLocation": "#" + }, + { + "valid": true, + "keywordLocation": "#/type", + "instanceLocation": "#" + }, + { + "valid": false, + "keywordLocation": "#/items", + "instanceLocation": "#", + "errors": [ + { + "valid": true, + "keywordLocation": "#/items/$ref", + "absoluteKeywordLocation": + "http://example.com/polygon#/items/$ref", + "instanceLocation": "#/0", + "annotations": [ + { + "valid": true, + "keywordLocation": "#/items/$ref", + "absoluteKeywordLocation": + "http://example.com/polygon#/definitions/point", + "instanceLocation": "#/0", + "annotations": [ + { + "valid": true, + "keywordLocation": "#/items/$ref/type", + "absoluteKeywordLocation": + "http://example.com/polygon#/definitions/point/type", + "instanceLocation": "#/0" + }, + { + "valid": true, + "keywordLocation": "#/items/$ref/properties", + "absoluteKeywordLocation": + "http://example.com/polygon#/definitions/point/properties", + "instanceLocation": "#/0" + }, + { + "valid": true, + "keywordLocation": "#/items/$ref/required", + "absoluteKeywordLocation": + "http://example.com/polygon#/definitions/point/required", + "instanceLocation": "#/0" + }, + { + "valid": true, + "keywordLocation": "#/items/$ref/additionalProperties", + "absoluteKeywordLocation": + "http://example.com/polygon#/definitions/point/additionalProperties", + "instanceLocation": "#/0" + } + ] + } + ] + }, + { + "valid": false, + "keywordLocation": "#/items/$ref", + "absoluteKeywordLocation": + "http://example.com/polygon#/items/$ref", + "instanceLocation": "#/1", + "errors": [ + { + "valid": false, + "keywordLocation": "#/items/$ref", + "absoluteKeywordLocation": + "http://example.com/polygon#/definitions/point", + "instanceLocation": "#/1", + "errors": [ + { + "valid": true, + "keywordLocation": "#/items/$ref/type", + "absoluteKeywordLocation": + "http://example.com/polygon#/definitions/point/type", + "instanceLocation": "#/1" + }, + { + "valid": true, + "keywordLocation": "#/items/$ref/properties", + "absoluteKeywordLocation": + "http://example.com/polygon#/definitions/point/properties", + "instanceLocation": "#/1" + }, + { + "valid": false, + "keywordLocation": "#/items/$ref/required", + "absoluteKeywordLocation": + "http://example.com/polygon#/definitions/point/required", + "instanceLocation": "#/1" + }, + { + "valid": false, + "keywordLocation": "#/items/$ref/additionalProperties", + "absoluteKeywordLocation": + "http://example.com/polygon#/definitions/point/additionalProperties", + "instanceLocation": "#/1", + "errors": [ + { + "valid": false, + "keywordLocation": "#/items/$ref/additionalProperties", + "absoluteKeywordLocation": + "http://example.com/polygon#/definitions/point/additionalProperties", + "instanceLocation": "#/1/z" + } + ] + } + ] + } + ] + } + ] + }, + { + "valid": false, + "keywordLocation": "#/minItems", + "instanceLocation": "#" + } + ] +}