检查 JSON Schema 中的不同嵌套属性

勒克拉姆

有没有办法在嵌套的 JSON 模式中实现等效于 CHECK 约束的 Postgres?假设我们有具有两个属性的数据,每个属性都有嵌套的属性。JSON Schema 如何使第一个对象的所需内容依赖于第二个对象?

我的真实案例场景是为 GeoJSON 对象构建一个 JSON 模式,该模式具有几何对象(即 Point 或 Polygon,或 null),以及“属性”对象中的其他属性。我想根据几何类型更改所需的属性。

我失败了以下两种解决方案:

  • 将“allOf”嵌套在“anyOf”中以涵盖所有可能性
  • 复制“定义”以获得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关键字有条件地应用子模式。

我们只想要ifthen为您解决。

两者的值都必须是 JSON Schema。

如果 的值if导致肯定的断言(当架构应用于实例并且验证成功时),则架构值then应用于实例。

这是架构。

我已在https://jsonschema.dev 上预加载了架构和数据,以便您可以对其进行实时测试。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "geometryIsPoint": {
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "Point"
        }
      }
    },
    "geometryAsPoint": {
      "required": [
        "coordinates"
      ],
      "properties": {
        "coordinates": {
          "type": "array"
        }
      }
    },
    "geometry": {
      "allOf": [
        {
          "if": {
            "$ref": "#/definitions/geometryIsPoint"
          },
          "then": {
            "$ref": "#/definitions/geometryAsPoint"
          }
        }
      ]
    }
  },
  "properties": {
    "geometry": {
      "$ref": "#/definitions/geometry"
    }
  }
}

该属性geometry引用了定义geometry

allOf 是一个模式数组。

allOf[0].if引用模式定义为的值geometryIsPoint

定义为的架构geometryIsPoint应用于该geometry值。如果它成功验证,则then应用引用的模式。

你不必使用引用来做任何这些,但我觉得它使意图更清晰。

根据需要扩展架构,allOf为您想要识别的任意数量的几何类型添加架构


编辑:

您遇到了else条件的条件,因为if验证失败。让我解释。

这是一个更新的架构,用于涵盖您修改后的用例。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "geometry": {
      "type": "object",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "enum": [
            "Point",
            "somethingelse",
            null
          ]
        }
      }
    },
    "geometryIsPoint": {
      "type": "object",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "Point"
        }
      }
    },
    "attributes": {
      "properties": {
        "name": {
          "type": "string"
        },
        "place": {
          "type": "string"
        }
      }
    },
    "partialAttributes": {
      "type": "object",
      "required": [
        "name"
      ]      
    },
    "fullAttributes": {
      "type": "object",
      "required": [
        "name",
        "place"
      ]
    },
    "conditionalAttributes": {
      "allOf": [
        {
          "if": {
            "required": [
              "geometry"
            ],
            "properties": {
              "geometry": {
                "$ref": "#/definitions/geometryIsPoint"
              }
            }
          },
          "then": {
            "required": [
              "attributes"
            ],
            "properties": {
              "attributes": {
                "$ref": "#/definitions/partialAttributes"
              }
            }
          },
          "else": {
            "required": [
              "attributes"
            ],
            "properties": {
              "attributes": {
                "$ref": "#/definitions/fullAttributes"
              }
            }
          }
        }
      ]
    }
  },
  "properties": {
    "attributes": {
      "$ref": "#/definitions/attributes"
    },
    "geometry": {
      "$ref": "#/definitions/geometry"
    }
  },
  "allOf": [
    {
      "$ref": "#/definitions/conditionalAttributes"
    }
  ]
}

这是一个JSON Schema 开发链接,您可以对其进行测试。

我们在这里所做的是分散关注。

所述的“形状”attributesgeometry在与相应的键定义所定义。这些模式不会断言这些对象中需要哪些键,只断言如果提供它们必须是什么。

因为$ref在模式中忽略了模式中的所有其他关键字(对于草案 7 或以下),在根级别,我conditionalAttributesallOf.

conditionalAttributes是一个定义的 JSON 模式。我已经使用过,allOf因此您可以添加更多条件检查。

的值conditionalAttributes.allOf[0].if是一个 JSON 模式,并应用于 JSON 实例的根。它需要一个键,geometry并且值为geometryIsPoint(如果省略required,您最终会遇到验证问题,因为省略该键将通过 if 条件)。

当实例产生trueif值模式断言(验证有效)时then值模式将在根级别应用。

因为它在根级别应用并且您想要检查嵌套属性的值,所以您必须properties像在架构的根级别一样使用它。就是您if/then/else在实例的不同深度上执行条件模式应用程序 ( ) 的方式。

您可以通过将架构值之一更改为false并查看错误来测试条件解析请记住,true并且false是有效的 JSON 模式,因此"then": false如果您希望then应用模式(如if模式断言验证正常),您可以写入导致错误

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

JSON SCHEMA - 如何检查数组中是否存在值

来自分类Dev

检查嵌套JSON中的键名

来自分类Dev

检查嵌套json中的键名

来自分类Dev

数字的MaxLength的JSON Schema属性

来自分类Dev

检查JSON中的变量

来自分类Dev

检查嵌套json响应的值

来自分类Dev

确保数组中的item属性在Json Schema中是唯一的?

来自分类Dev

基于属性值的条件Json Schema验证

来自分类Dev

Json Schema,请考虑未指定的属性

来自分类Dev

JSON Schema:如何扩展更多属性?

来自分类Dev

在React中阅读schema.org JSON

来自分类Dev

PatternProperties 中的 JSON Schema 严格类型

来自分类Dev

如何检查json的嵌套列表中是否存在密钥?

来自分类Dev

如何检查json中是否存在嵌套键?

来自分类Dev

JSON 模式中的条件检查

来自分类Dev

如何检查哈希中的嵌套属性?

来自分类Dev

如何检查哈希中的嵌套属性?

来自分类Dev

从 json 中引用 JSON Schema 类似 XML 引用 XML 模式

来自分类Dev

JavaScript如何检查json中是否缺少属性

来自分类Dev

如何检查JSON数据中是否存在值/属性

来自分类Dev

检查m子中的json键或对象属性

来自分类Dev

对数组中某些对象属性的 JSON 模式条件检查

来自分类Dev

JSON-LD附加属性,这些属性不在字典schema.org中

来自分类Dev

JSON-LD示例将“名称”属性用于“人”,但该属性不在Schema.org中

来自分类Dev

如果可选属性无效,则JSON Schema引发验证错误

来自分类Dev

JSON Schema 有条件地要求属性

来自分类Dev

如何使用 Json.NET.Schema 要求属性?

来自分类Dev

json-schema - 允许在所需属性中进行逻辑或

来自分类Dev

javascript - 检查嵌套对象上的属性与对象中的“属性”失败

Related 相关文章

热门标签

归档