将 oneOf 嵌套在任何 JSON 模式中
Posted
技术标签:
【中文标题】将 oneOf 嵌套在任何 JSON 模式中【英文标题】:Nesting oneOf in anyOf for a JSON Schema 【发布时间】:2020-01-30 01:05:56 【问题描述】:这里是 JSON Schema 和 JSON 如下链接中提供的用于说明目的。
JSON Schema and the JSON
格式: 数组中的单个 JSON 对象(具有它们的附加属性并且可能与数组中的其他对象不同)可以是任何 3 个区域:“美国”、“亚洲”和“欧洲”,并且至少区域对象的类型应该在那里。这可以通过数组 minItems 属性来实现)
问题陈述:
数组中的单个 JSON 对象可以是任何 3 个区域:'america'、'asia' 和 'europe' 并且至少应该有区域对象的类型
==> 我可以通过将所有区域对象放在 anyOf 数组中来解决这个问题,因为我想匹配至少一个有效区域对象。
JSON 对象“亚洲”或“欧洲”可以与其他区域类型一起存在。两者不能共存。
==> 我尝试使用 'oneOf' 但它通过了 ajv 验证。实际上它应该失败。任何人都可以帮忙。谢谢
JSON 架构
"type": "object",
"properties":
"stat_data":
"type": "array",
"minItems": 1,
"items":
"type": "object",
"properties": ,
"anyOf": [
"required": ["region"],
"properties":
"region":
"enum": ["america"]
,
"country":
"type": "string"
,
"population":
"type": "string"
,
"oneOf": [
"required": ["region"],
"properties":
"region":
"enum": ["asia"]
,
"country":
"type": "string"
,
"details":
"type": "object",
"properties":
"language":
"type": "string"
,
"tz":
"type": "string"
,
"required": ["region"],
"properties":
"region":
"enum": ["europe"]
,
"country":
"type": "string"
,
"language":
"type": "string"
]
]
JSON 对象失败,因为“亚洲”和“欧洲”类型的对象不能共存。
"stat_data": [
"region": "america",
"country": "USA",
"states": "50"
,
"region": "asia",
"country": "Japan",
"details":
"language": "Japanese",
"tz": "utc+9.00"
,
"region": "europe",
"country": "finland",
"language": "Finnish"
]
只有“亚洲”类型对象存在才能通过的 JSON 对象。
"stat_data": [
"region": "america",
"country": "USA",
"states": "50"
,
"region": "asia",
"country": "Japan",
"details":
"language": "Japanese",
"tz": "utc+9.00"
]
要传递的 JSON 对象仅存在“欧洲”类型的对象。
"stat_data": [
"region": "america",
"country": "USA",
"states": "50"
,
"region": "europe",
"country": "finland",
"language": "Finnish"
]
【问题讨论】:
这很有帮助,除了用文字解释什么应该通过和失败,你还包括一个应该通过和失败的示例实例。有时文字比实际看到数据更难=] 我在问题中添加了一些正确和不正确的示例,并将我尝试过的 json 模式作为链接的一部分。 啊,这可能比我预期的要容易。我打算今天发布一个答案!提示:它涉及使用not
。
【参考方案1】:
我知道为什么您尝试了您所做的方法,但是它没有按预期工作,因为您已经定义了,数组中的每个项目可能是 america
或(europe
或 asia
),其中不是你想要的。
请记住,items
将值模式应用于数组中的每个元素。它对整个阵列本身没有任何限制。 contains
检查数组中的至少一项是否根据其值模式进行验证。
你想说的是,数组中的每一项可能有america
或europe
或asia
,但如果包含asia
,则数组可能不包含europe
,反之亦然。
我已经重构了架构并进行了一些更改。
希望您也可以在使用oneOf
>>(contains
和not
> contains
)时看到意图很明确。
JSON Schema 通过添加约束来工作。您通常不能通过省略来定义约束。
JSON Schema and data validation demo
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions":
"containtsAsia":
"contains":
"properties":
"region":
"const": "asia"
,
"containsEurope":
"contains":
"properties":
"region":
"const": "europe"
,
"type": "object",
"properties":
"stat_data":
"type": "array",
"minItems": 1,
"items":
"type": "object",
"properties":
"region":
"enum": [
"america",
"asia",
"europe"
]
,
"country":
"type": "string"
,
"population":
"type": "string"
,
"oneOf": [
"allOf": [
"$ref": "#/definitions/containtsAsia"
,
"not":
"$ref": "#/definitions/containsEurope"
]
,
"allOf": [
"$ref": "#/definitions/containsEurope"
,
"not":
"$ref": "#/definitions/containtsAsia"
]
]
【讨论】:
真诚感谢您按照我的要求所做的努力。此外,我们不能使用“anyOf”而不是“oneOf”,因为我们需要至少一个 json 对象来获得资格。 'oneOf' ==> 一个(并且只有一个)包含的模式必须针对实例值进行验证。 AnyOf :一个或多个包含的模式必须针对实例值进行验证。 Ref: liquid-technologies.com/reference/xmlstudio/… 这是我的观点,有时候,理解 JSON 规范很难解释。 不客气。如果您希望表达更多感谢,请在我的 *** 个人资料中提供指向我的支持页面的链接。 您可以在这种情况下使用anyOf
,但这只是因为约束已完全表达。通常当使用anyOf
并且人们遇到问题时,这是因为负相反约束没有在其他模式中表达,并且它以这种方式通过验证。
当然。 kofi 上的任何贝宝选项而不是条纹?
是的。启用它。以前只允许使用 Stripe,因为它们提供了更好的价格,但我应该明白并不是每个人都可以或想要使用它。谢谢!以上是关于将 oneOf 嵌套在任何 JSON 模式中的主要内容,如果未能解决你的问题,请参考以下文章
Json Schema:仅当深层嵌套对象中存在特定属性时才需要属性
任何动态创建模式以支持即席 JSON 对象映射持久性的框架?
如何使用 AWS 胶水获取存储在 s3 中的模式或已处理的嵌套 json 文件压缩(gzip)?