较新的 jsonschema 草稿中有
unevaluatedProperties
关键字,我明白其目的是什么。
引入它是因为“additionalProperties: false”不允许未知属性的习惯用法使模式不可扩展:我们无法在不修改模式的情况下扩展模式,将其放入 allOf 构造中将不起作用。为此,现在有 unevaluatedProperties。
可以在此处找到规范https://json-schema.org/draft/2020-12/json-schema-core#section-11.3.
但我想在技术层面上了解 unevaluatedProperties 的确切定义。我真的无法理解这个定义
“unevaluatedProperties”验证仅适用于未出现在适用于正在验证的实例位置的“properties”、“patternProperties”、“additionalProperties”或“unevaluatedProperties”注释结果中的实例名称的子值。
这是什么意思?
特别是:
... applies only to the child values of instance names ...
实例名称如何具有子值?
instance names that .. do not appear in the [...] "additionalProperties" ...
。怎么可能呢? otherProperties 不列出任何名称(与至少列出名称模式的properties 或patternProperties 相反)。
也许一些例子:以下 jsonschema 的预期行为是什么?
{
"anyOf": [
true,
"not": { "properties": { "a": true } } // <<<< other lines below
],
"unevaluatedProperties": false
}
有趣的 JSON 候选实例是
{}
、{ "a": 1 }
{ "b": 1 }
上述模式的变体带有“<<<<" line replaced with
(我强烈怀疑“not”结构并没有真正改变任何东西,但让我们将其包含进来只是为了好玩。或者将其更改为单独的
if
关键字。)
我不是在问验证器正在响应什么,而是在问根据模式规范的正确行为是什么。请解释一下:-)
在
unevaluated*
关键字之前,组合关键字在可扩展模式和组合方面存在一些困难。
举这些例子
allOf
要求每个子模式都通过验证。定义了 allOf
的 additionalProperties: false
构造中的任何子模式都会破坏任何相邻子模式的验证,因为除了定义的属性之外,不允许使用其他属性。
additionalProperties
无法查看其他模式:相邻、父或子。
$schema: http://json-schema.org/draft-07/schema#
allOf:
- properties:
name:
type: string
- properties:
age:
type: number
additionalProperties: false
# failing
name: john
#failing
name: john
age: 10
# passing
age: 10
这是一个很常见却被极大误解的例子
我们回到这个评论:
additionalProperties
无法查看其他模式:相邻、父级或子级。
在这种情况下,模式的根定义了
allOf
和 additionalProperties: false
。
对 JSON 模式的一个关键理解是每个模式资源都是独立验证的。
此示例定义了 3 个唯一的模式:根、
allOf
中的第一个和第二个索引。根模式将阻止任何未定义的属性在根。因此,allOf
将始终评估为 false
,并且此模式将永远不允许任何传递实例。
additionalProperties: false
allOf:
- properties:
name:
type: string
- properties:
age:
type: number
# failing
name: john
age: 10
# failing
age: 10
# failing
name: john
我们现在有了一个可以满足许多 JSON Schema 用户的预期行为的解决方案。不过,这是一种“类似继承”的模式,并不像编程语言中那样严格继承。
unevaluatedProperties
的工作方式与大多数人期望的
allOf
和 additionalProperties: false
组合的工作方式相同。它允许验证器“查看”组合关键字中定义的子模式。它仅在单向方向上工作,即定义关键字的子模式。它无法查看相邻或父架构。
$schema: https://json-schema.org/draft/2020-12/schema
unevaluatedProperties: false
allOf:
- properties:
name:
type: string
- properties:
age:
type: number
# passing
name: john
# passing
age: 10
# passing
name: john
age: 10
# failing
name: john
age: 10
month: January
显然,这些都是非常基本的示例,但希望它能够很好地解释该行为,让您能够了解如何将其用于更复杂的模式。