JsonSchema未通过oneOf验证

时间:2015-01-06 13:08:33

标签: jsonschema tv4

需要帮助才能找到此架构的错误。它有一个运算符。 架构在这里:

   `{
    "type": "object",
    "required": [
        "type",
        "body"
    ],
    "properties": {
        "type": {
            "description": "type of the document to post",
            "type": "string",
            "enum": [
                "123",
                "456"                    
            ]
        },
        "body": {
            "type": "object",
            "description": "body",
            "oneOf": [{
                "$ref": "#/definitions/abc",
                "$ref": "#/definitions/def"
            }]
        }
    },
    "definitions": {
        "abc": {                
            "type": "array",
            "description": "abc",
           "properties" : {
               "name" : { "type" : "string"  }
         }
        },
        "def": {                
            "type": "array",
            "description": "users","properties" : {
               "name" : { "type" : "string"  }
         }
        }
    }
}`

我的Json是这样的:

  `{
            "type": "123",
            "body": {
                "abc": [{
                    "name": "test"
                }]
            }
        }`

它没有使用tv4验证,我也尝试了这个online tool。它没有oneOf运算符。否则它不会验证任何工具。

修改

阅读完答案后,我修改了架构。新架构是:

{
"type": "object",
"properties": {
    "type": {
        "description": "type of the document to post",
        "type": "string",

    },
    "body": {
        "type": "object",
        "description": "body",
        "properties": {
            "customers": {
                "type": "array"
            }
        },
        "anyOf": [
            {
                "title": "customers prop",
                "properties": { 
                    "customers": {
                        "type": "array",
                        "description": "customers",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        ]
    }
  }
}

json就在这里

{
"type": "customer",
"body": {
    "none": [
        {
            "name": "test"
        }
    ]
  }
}

但它验证了。我想强制执行一个"客户"或"用户"在身体里。为了测试我已经从身体中删除了用户。

Pl帮助。

3 个答案:

答案 0 :(得分:3)

问题是数据正在传递两个子模式。 oneOf表示"匹配完全一个" - 如果你想"匹配至少一个",那么使用anyOf

实际上,两个子模式都将传递所有数据。原因是在处理数组时会忽略properties

您可能想要做的是指定数组中的属性。为此,您需要items关键字:

"definitions": {
    "abc": {                
        "type": "array",
        "items": {
            "type": "object",
            "properties" : {
                "name" : { "type" : "string"  }
            }
        }
    }
}

(您还需要添加一些不同的约束 - 目前,"abc""def"定义除了description之外都是相同的,这使得{oneOf 1}}不可能,因为它总是匹配两者或两者都不匹配。)

答案 1 :(得分:2)

由于您具有根级别的类型,您可能希望oneOf语句检查具有“customer”类型的对象是否在正文中有客户(即使我建议跳过正文并将客户和用户直接放在root中对象)。

这适用于您的示例,将要求类型为“customer”的对象具有带有“customers”的正文,并且为了阐明匹配,我让客户拥有属性“name”,而用户具有“username”:

{
  "type": "object",
  "properties": {
    "type": { "type": "string" },
    "body": {
      "type": "object",
      "properties": {
        "customers": { 
          "type": "array",
          "items": { "$ref": "#/definitions/customer" }
        },
        "users": {
          "type": "array",
          "items": { "$ref": "#/definitions/user" }
        }
      }
    }
  },
  "definitions": {
    "customer": {
      "type": "object",
      "properties": { "name": { "type": "string" } },
      "required": [ "name" ]
    },
    "user": {
      "type": "object",
      "properties": { "username": { "type": "string" } },
      "required": [ "username" ]
    }
  },
  "oneOf": [
    {
      "properties": {
        "type": {
          "pattern": "customer"
        },
        "body": {
          "required": [ "customers" ]
        }
      }
    },
    {
      "properties": {
        "type": {
          "pattern": "user"
        },
        "body": {
          "required": [ "users" ]
        }
      }
    }
  ]
}

答案 2 :(得分:1)

使用"type": "array"时,项目类型在"items"属性中定义,而不是"properties"属性... oneOf中的两种类型都相同,但只有一个必须匹配。

尝试

      ...
      "definitions": {
        "abc": {                
            "type": "array",
            "description": "abc",
           "items" : {
               "name" : { "type" : "string"  }
         }
        },
        "def": {                
            "type": "array",
            "description": "users",
            "items" : {
               "username" : { "type" : "string"  }
            }
        }
    }