如何向 JSON 架构中引用架构中的属性添加附加约束?

问题描述 投票:0回答:1

我正在尝试编写一个 JSON 架构以在引用的架构中施加额外的必需属性。我查看了herehere,但是

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 ]
        ]
      ]
    }
  }
}
geojson jsonschema json-schema-validator
1个回答
0
投票

您尝试的架构存在一些问题

  • 07 草案的
    $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 模式中定义的,并且看起来这就是您想要此要求的位置,所以这就是您实现这一目标的方式。

JSON 模式定义

{
  "$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 ]
        ]
      ]
    }
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.