|
| 1 | +# Schema violation reporting |
| 2 | + |
| 3 | +(Unreleased as of 2017-09-20) |
| 4 | + |
| 5 | +When validating an instance against a JSON Schema, |
| 6 | +it is often desirable to report not only whether the instance is valid, |
| 7 | +but also the ways in which it violates the schema. |
| 8 | + |
| 9 | +The `SchemaValidator` class |
| 10 | +collects errors encountered during validation |
| 11 | +into a JSON `Value`. |
| 12 | +This error object can then be accessed as `validator.GetError()`. |
| 13 | + |
| 14 | +The structure of the error object is subject to change |
| 15 | +in future versions of RapidJSON, |
| 16 | +as there is no standard schema for violations. |
| 17 | +The details below this point are provisional only. |
| 18 | + |
| 19 | +[TOC] |
| 20 | + |
| 21 | +# General provisions {#General} |
| 22 | + |
| 23 | +Validation of an instance value against a schema |
| 24 | +produces an error value. |
| 25 | +The error value is always an object. |
| 26 | +An empty object `{}` indicates the instance is valid. |
| 27 | + |
| 28 | +* The name of each member |
| 29 | + corresponds to the JSON Schema keyword that is violated. |
| 30 | +* The value is either an object describing a single violation, |
| 31 | + or an array of such objects. |
| 32 | + |
| 33 | +Each violation object contains two string-valued members |
| 34 | +named `instanceRef` and `schemaRef`. |
| 35 | +`instanceRef` contains the URI fragment serialization |
| 36 | +of a JSON Pointer to the instance subobject |
| 37 | +in which the violation was detected. |
| 38 | +`schemaRef` contains the URI of the schema |
| 39 | +and the fragment serialization of a JSON Pointer |
| 40 | +to the subschema that was violated. |
| 41 | + |
| 42 | +Individual violation objects can contain other keyword-specific members. |
| 43 | +These are detailed further. |
| 44 | + |
| 45 | +For example, validating this instance: |
| 46 | + |
| 47 | +~~~json |
| 48 | +{"numbers": [1, 2, "3", 4, 5]} |
| 49 | +~~~ |
| 50 | + |
| 51 | +against this schema: |
| 52 | + |
| 53 | +~~~json |
| 54 | +{ |
| 55 | + "type": "object", |
| 56 | + "properties": { |
| 57 | + "numbers": {"$ref": "numbers.schema.json"} |
| 58 | + } |
| 59 | +} |
| 60 | +~~~ |
| 61 | + |
| 62 | +where `numbers.schema.json` refers |
| 63 | +(via a suitable `IRemoteSchemaDocumentProvider`) |
| 64 | +to this schema: |
| 65 | + |
| 66 | +~~~json |
| 67 | +{ |
| 68 | + "type": "array", |
| 69 | + "items": {"type": "number"} |
| 70 | +} |
| 71 | +~~~ |
| 72 | + |
| 73 | +produces the following error object: |
| 74 | + |
| 75 | +~~~json |
| 76 | +{ |
| 77 | + "type": { |
| 78 | + "instanceRef": "#/numbers/2", |
| 79 | + "schemaRef": "numbers.schema.json#/items", |
| 80 | + "expected": ["number"], |
| 81 | + "actual": "string" |
| 82 | + } |
| 83 | +} |
| 84 | +~~~ |
| 85 | + |
| 86 | +# Validation keywords for numbers {#numbers} |
| 87 | + |
| 88 | +## multipleOf {#multipleOf} |
| 89 | + |
| 90 | +* `expected`: required number strictly greater than 0. |
| 91 | + The value of the `multipleOf` keyword specified in the schema. |
| 92 | +* `actual`: required number. |
| 93 | + The instance value. |
| 94 | + |
| 95 | +## maximum {#maximum} |
| 96 | + |
| 97 | +* `expected`: required number. |
| 98 | + The value of the `maximum` keyword specified in the schema. |
| 99 | +* `exclusiveMaximum`: optional boolean. |
| 100 | + This will be true if the schema specified `"exclusiveMaximum": true`, |
| 101 | + and will be omitted otherwise. |
| 102 | +* `actual`: required number. |
| 103 | + The instance value. |
| 104 | + |
| 105 | +## minimum {#minimum} |
| 106 | + |
| 107 | +* `expected`: required number. |
| 108 | + The value of the `minimum` keyword specified in the schema. |
| 109 | +* `exclusiveMinimum`: optional boolean. |
| 110 | + This will be true if the schema specified `"exclusiveMinimum": true`, |
| 111 | + and will be omitted otherwise. |
| 112 | +* `actual`: required number. |
| 113 | + The instance value. |
| 114 | + |
| 115 | +# Validation keywords for strings {#strings} |
| 116 | + |
| 117 | +## maxLength {#maxLength} |
| 118 | + |
| 119 | +* `expected`: required number greater than or equal to 0. |
| 120 | + The value of the `maxLength` keyword specified in the schema. |
| 121 | +* `actual`: required string. |
| 122 | + The instance value. |
| 123 | + |
| 124 | +## minLength {#minLength} |
| 125 | + |
| 126 | +* `expected`: required number greater than or equal to 0. |
| 127 | + The value of the `minLength` keyword specified in the schema. |
| 128 | +* `actual`: required string. |
| 129 | + The instance value. |
| 130 | + |
| 131 | +## pattern {#pattern} |
| 132 | + |
| 133 | +* `actual`: required string. |
| 134 | + The instance value. |
| 135 | + |
| 136 | +(The expected pattern is not reported |
| 137 | +because the internal representation in `SchemaDocument` |
| 138 | +does not store the pattern in original string form.) |
| 139 | + |
| 140 | +# Validation keywords for arrays {#arrays} |
| 141 | + |
| 142 | +## additionalItems {#additionalItems} |
| 143 | + |
| 144 | +This keyword is reported |
| 145 | +when the value of `items` schema keyword is an array, |
| 146 | +the value of `additionalItems` is `false`, |
| 147 | +and the instance is an array |
| 148 | +with more items than specified in the `items` array. |
| 149 | + |
| 150 | +* `disallowed`: required integer greater than or equal to 0. |
| 151 | + The index of the first item that has no corresponding schema. |
| 152 | + |
| 153 | +## maxItems and minItems {#maxItems} |
| 154 | + |
| 155 | +* `expected`: required integer greater than or equal to 0. |
| 156 | + The value of `maxItems` (respectively, `minItems`) |
| 157 | + specified in the schema. |
| 158 | +* `actual`: required integer greater than or equal to 0. |
| 159 | + Number of items in the instance array. |
| 160 | + |
| 161 | +## uniqueItems {#uniqueItems} |
| 162 | + |
| 163 | +* `duplicates`: required array |
| 164 | + whose items are integers greater than or equal to 0. |
| 165 | + Indices of items of the instance that are equal. |
| 166 | + |
| 167 | +(RapidJSON only reports the first two equal items, |
| 168 | +for performance reasons.) |
| 169 | + |
| 170 | +# Validation keywords for objects |
| 171 | + |
| 172 | +## maxProperties and minProperties {#maxProperties} |
| 173 | + |
| 174 | +* `expected`: required integer greater than or equal to 0. |
| 175 | + The value of `maxProperties` (respectively, `minProperties`) |
| 176 | + specified in the schema. |
| 177 | +* `actual`: required integer greater than or equal to 0. |
| 178 | + Number of properties in the instance object. |
| 179 | + |
| 180 | +## required {#required} |
| 181 | + |
| 182 | +* `missing`: required array of one or more unique strings. |
| 183 | + The names of properties |
| 184 | + that are listed in the value of the `required` schema keyword |
| 185 | + but not present in the instance object. |
| 186 | + |
| 187 | +## additionalProperties {#additionalProperties} |
| 188 | + |
| 189 | +This keyword is reported |
| 190 | +when the schema specifies `additionalProperties: false` |
| 191 | +and the name of a property of the instance is |
| 192 | +neither listed in the `properties` keyword |
| 193 | +nor matches any regular expression in the `patternProperties` keyword. |
| 194 | + |
| 195 | +* `disallowed`: required string. |
| 196 | + Name of the offending property of the instance. |
| 197 | + |
| 198 | +(For performance reasons, |
| 199 | +RapidJSON only reports the first such property encountered.) |
| 200 | + |
| 201 | +## dependencies {#dependencies} |
| 202 | + |
| 203 | +* `errors`: required object with one or more properties. |
| 204 | + Names and values of its properties are described below. |
| 205 | + |
| 206 | +Recall that JSON Schema Draft 04 supports |
| 207 | +*schema dependencies*, |
| 208 | +where presence of a named *controlling* property |
| 209 | +requires the instance object to be valid against a subschema, |
| 210 | +and *property dependencies*, |
| 211 | +where presence of a controlling property |
| 212 | +requires other *dependent* properties to be also present. |
| 213 | + |
| 214 | +For a violated schema dependency, |
| 215 | +`errors` will contain a property |
| 216 | +with the name of the controlling property |
| 217 | +and its value will be the error object |
| 218 | +produced by validating the instance object |
| 219 | +against the dependent schema. |
| 220 | + |
| 221 | +For a violated property dependency, |
| 222 | +`errors` will contain a property |
| 223 | +with the name of the controlling property |
| 224 | +and its value will be an array of one or more unique strings |
| 225 | +listing the missing dependent properties. |
| 226 | + |
| 227 | +# Validation keywords for any instance type {#anytypes} |
| 228 | + |
| 229 | +## enum {#enum} |
| 230 | + |
| 231 | +This keyword has no additional properties |
| 232 | +beyond `instanceRef` and `schemaRef`. |
| 233 | + |
| 234 | +* The allowed values are not listed |
| 235 | + because `SchemaDocument` does not store them in original form. |
| 236 | +* The violating value is not reported |
| 237 | + because it might be unwieldy. |
| 238 | + |
| 239 | +If you need to report these details to your users, |
| 240 | +you can access the necessary information |
| 241 | +by following `instanceRef` and `schemaRef`. |
| 242 | + |
| 243 | +## type {#type} |
| 244 | + |
| 245 | +* `expected`: required array of one or more unique strings, |
| 246 | + each of which is one of the seven primitive types |
| 247 | + defined by the JSON Schema Draft 04 Core specification. |
| 248 | + Lists the types allowed by the `type` schema keyword. |
| 249 | +* `actual`: required string, also one of seven primitive types. |
| 250 | + The primitive type of the instance. |
| 251 | + |
| 252 | +## allOf, anyOf, and oneOf {#allOf} |
| 253 | + |
| 254 | +* `errors`: required array of at least one object. |
| 255 | + There will be as many items as there are subschemas |
| 256 | + in the `allOf`, `anyOf` or `oneOf` schema keyword, respectively. |
| 257 | + Each item will be the error value |
| 258 | + produced by validating the instance |
| 259 | + against the corresponding subschema. |
| 260 | + |
| 261 | +For `allOf`, at least one error value will be non-empty. |
| 262 | +For `anyOf`, all error values will be non-empty. |
| 263 | +For `oneOf`, either all error values will be non-empty, |
| 264 | +or more than one will be empty. |
| 265 | + |
| 266 | +## not {#not} |
| 267 | + |
| 268 | +This keyword has no additional properties |
| 269 | +apart from `instanceRef` and `schemaRef`. |
0 commit comments