我正在尝试编写 JSONSchema 以在嵌套的 GEOJson 要素对象中强加一些必需的属性。我查看了here和here,但是
check-jsonschema
告诉我,我需要顶层的属性,而不是嵌套的properties
对象中的属性。如何在嵌套对象上添加约束?
尝试的架构:
{
"$schema": "https://json-schema.org/draft-07/schema#",
"$id": "https://example.com/sample.schema.json",
"type": "object",
"properties": {
"boundaries": {
"description": "Boundaries",
"allOf": [
{ "$ref": "http://geojson.org/schema/Feature.json" },
{
"geometry": {
"oneOf": [
{ "$ref": "http://geojson.org/schema/MultiPolygon.json" },
{ "$ref": "http://geojson.org/schema/Polygon.json" }
],
"additionalProperties": false
}
},
{
"type": "object",
"required" : ["name"]
}
]
}
}
}
我希望以下操作成功,但上面的验证器要求我将
name
与 type
、properties
和 geometry
置于同一级别。
JSON 实例:
{
"boundaries": {
"type": "Feature",
"properties": {
"name": "Bounded Place",
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[ -100.0, 40.0 ],
[ -100.0, 45.0 ],
[ -110.0, 45.0 ],
[ -110.0, 40.0 ]
]
]
}
}
}
您尝试的架构存在一些问题
$schema
声明必须使用 http
而不是 https
。这不被认为是网络可到达的 uri,而是元模式的标识符。 src:draft-07 规范allOf
子模式未正确定义属性 geometry
。该模式不受约束地完成,并且允许任何数据通过。您只能使用定义的 properties
关键字来约束属性。您是否想对引用模式未验证的几何关键字添加额外的验证?additionalProperties: false
也会使整个模式在任何实例中失败,因为 allOf
的所有子模式都必须有效。这会失败的原因有两个。首先,当使用任何组合关键字(allOf、oneOf、anyOf)定义 additionalProperties:false
且未定义 properties
关键字时,模式将永远不会传递任何数据实例,因为附加属性受到根模式的约束,并且确实如此没有“触及”子模式的 oneOf
数组,因此它不知道根处有任何已定义的属性,因此它无法验证任何模式。其次,当您将其中一个子模式限制为 allOf
内没有其他属性时,如果其他子模式的属性未在具有 additionalProperties: false
的模式中定义,则所有模式都将失败。required: ["name"]
位于错误的嵌套级别,因为 Feature.json
模式有一个名为 properties
的属性(这可能会令人困惑),而这就是您在实例中定义 name
的位置。根据我的理解,您希望在数据实例中需要
name
。为此,您需要在 allOf
子模式中定义嵌套结构,然后需要该属性。因为属性 properties
是在 geoJSON 模式中定义的,并且看起来这就是您想要此要求的位置,所以这就是您实现这一目标的方式。
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/sample.schema.json",
"type": "object",
"properties": {
"boundaries": {
"description": "Boundaries",
"allOf": [
{
"type": "object",
"properties": {
"properties": {
"required": [
"name"
]
}
}
},
{
"$ref": "https://geojson.org/schema/Feature.json"
}
]
}
}
}
{
"boundaries": {
"type": "Feature",
"properties": {
"name": "Bounded Place"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[ -100.0, 40.0 ],
[ -100.0, 45.0 ],
[ -110.0, 45.0 ],
[ -110.0, 40.0 ]
]
]
}
}
}