【发布时间】:2019-11-25 01:03:11
【问题描述】:
有没有办法在嵌套的 JSON Schema 中实现与 CHECK 约束等效的 Postgres?假设我们有具有两个属性的数据,每个属性都有嵌套属性。 JSON Schema 如何让第一个对象所需的内容依赖于第二个?
我的真实案例场景是为 GeoJSON 对象构建 JSON 模式,该对象具有几何对象(即点或多边形,或 null)以及“属性”对象中的其他属性。我想根据几何类型更改所需的属性。
以下两种解决方案都失败了:
- 在“anyOf”中嵌套“allOf”以涵盖所有可能性
- 复制“定义”以获得 attributes_no_geom、geometry_no_geom、attribute_with_geom 和 geometry_with_geom,并在“anyOf”中声明它们
这将验证,因为缺少几何图形的属性/位置覆盖:
{
"attributes": {
"name": "Person2",
"place": "City2"
},
"geometry": null
}
这也将验证,因为几何不再需要属性/位置:
{
"attributes": {
"name": "Person1"
},
"geometry": {
"type": "Point",
"coordinates": []
}
}
编辑
基于 Relequestual 的回答,这是我得到的不令人满意的结果:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"geometryIsPoint": {
"type": "object",
"required": ["type"],
"properties": {
"type": {
"const": "Point"
}
}
},
"partialAttributes": {
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string"
},
"place": {
"type": "string"
}
}
},
"fullAttributes": {
"type": "object",
"required": ["name", "place"],
"properties": {
"name": {
"type": "string"
},
"place": {
"type": "string"
}
}
},
"conditionalAttributes": {
"allOf": [
{
"if": {
"$ref": "#/definitions/geometryIsPoint"
},
"then": {
"$ref": "#/definitions/partialAttributes"
},
"else": {
"$ref": "#/definitions/fullAttributes"
}
}
]
}
},
"properties": {
"attributes": {
"$ref": "#/definitions/conditionalAttributes"
},
"geometry": {
"$ref": "#/definitions/geometryIsPoint"
}
}
}
如果删除 attributes/place 属性,此架构将不会验证以下内容。
{
"attributes": {
"name": "Person",
"place": "INVALID IF THIS LINE IS REMOVED ;-("
},
"geometry": {
"type": "Point",
"coordinates": {}
}
}
【问题讨论】:
-
您可以使用
if/then/else关键字,包裹在allOf中来实现您想要的。我希望在今天的某个时候为您提供更全面的答案。 -
我假设您正在使用支持 Draft-7 JSON 模式的库。对吗?
-
是的,我使用的是 Draft-7 JSON 模式。感谢您的建议。我将尝试条件语句,但我对文档的理解是条件块的内容总是引用它们声明的属性,因此,在上面的示例中,我不能做类似
if geometry/type then require something in attributes? -
有可能。我会告诉你多久=]
标签: json jsonschema json-schema-validator