将 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 或(europeasia),其中不是你想要的。

请记住,items 将值模式应用于数组中的每个元素。它对整个阵列本身没有任何限制。 contains 检查数组中的至少一项是否根据其值模式进行验证。

你想说的是,数组中的每一项可能有americaeuropeasia,但如果包含asia,则数组可能不包含europe,反之亦然。

我已经重构了架构并进行了一些更改。

希望您也可以在使用oneOf >>(containsnot > 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)?

在 Hive 中,这种模式如何从 json 数组中识别嵌套的 json?

如何定义至少需要许多属性之一的 JSON 模式

使用 pyspark 解析 JSON 时嵌套动态模式不起作用