繁体   English   中英

Json Schema 多态性使用 anyOf 验证

[英]Json Schema Polymorphism Validate with anyOf

我有一只Pet object,它可以是dog也可以是cat ,根据它们发出的noise ,我希望能够验证其他字段。 架构:

{
  "$id": "http://example.com",
  "definitions": {
    "pet": {
      "type": "object",
      "properties": {
        "noise": {
          "enum": [
            "bark",
            "meow"
          ]
        }
      }
    },
    "dog": {
      "$ref": "#/definitions/pet",
      "properties": {
        "noise": {
          "const": "bark"
        },
        "tail": {
          "enum": [
            "short",
            "long"
          ]
        }
      }
    },
    "cat": {
      "$ref": "#/definitions/pet",
      "properties": {
        "noise": {
          "const": "meow"
        },
        "tail": {
          "enum": [
            "wavy",
            "slinky"
          ]
        }
      }
    }
  },
  "type": "object",
  "properties": {
    "pets": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "$ref": "#/definitions/dog",
            "$ref": "#/definitions/cat"
          }
        ]
      }
    }
  }
}

这在通过以下方式运行 json 时有效:

{"pets":[{"noise":"meow","tail":"wavy"}]}

但不是在运行时:

{"pets":[{"noise":"bark","tail":"long"}]}
[$.pets[0].tail: does not have a value in the enumeration [wavy, slinky], $.pets[0].noise: must be a constant value meow]

或者

{"pets":[{"noise":"bark","tail":"long"},{"noise":"meow","tail":"wavy"}]}
[$.pets[0].tail: does not have a value in the enumeration [wavy, slinky], $.pets[0].noise: must be a constant value meow]

我可以通过在 json 模式中使用if/else来完成这项工作,但需要另一种类型来避免循环依赖:

  "petWithConstraints": {
    "$ref":"#/definitions/pet",
    "allOf": [
        {
          "if": {
            "properties": {
              "noise": {
                "const": "bark"
              }
            }
          },
          "then": {
            "$ref": "#/definitions/dog"
          }
        },
        {
          "if": {
            "properties": {
              "noise": {
                "const": "meow"
              }
            }
          },
          "then": {
            "$ref": "#/definitions/cat"
          }
        }
      ]
    }
  }

这意味着对于每个新定义,它还需要另一个if语句。

有没有更好的方法来做到这一点? (没有额外的定义/if 语句)

对于遇到这种情况的人来说,这是一个语法错误。 每个 ref 都应该在它自己的代码块中。

架构的更正部分如下所示:

"properties": {
    "pets": {
      "type": "array",
      "items": {
        "anyOf": [
          { // Notice each $ref is encapsulated in it's own block
            "$ref": "#/definitions/cat"
          },
          {
            "$ref": "#/definitions/dog"
          }
        ]
      }
    }
  }

通过运行以下 json 给出了预期的结果

{"pets":[{"noise":"bark","tail":"long"},{"noise":"meow","tail":"wavy"}]}
[]
{"pets":[{"noise":"bark","tail":"long"},{"noise":"meow","tail":"wavy"},{"noise":"meow","tail":"slinky"},{"noise":"bark","tail":"short"}]}
[]
{"pets":[{"noise":"bark","tail":"long"},{"noise":"meow","tail":"wavy"},{"noise":"meow","tail":"slinky"},{"noise":"bark","tail":"short"},{"noise":"meow","tail":"short"}]}
[$.pets[4]: should be valid to one and only one of the schemas ]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM