Json 架构匹配 'anyOf'

Json Schema matching with 'anyOf'

我希望能够管理 'objects' 的 json 数组,其中每个对象都有一个类型和属性,如果强制 属性 是缺少一个对象。

这是我尝试这样做(不包括数组部分),声明两种对象类型并说明 json 中的对象可以是这些类型之一:

{
  'definitions': 
  {
    'typeone': 
    {
      'type': 'object',
      'properties': 
      {
        'xtype': {'type':'string', 'const':'typeone'},
        'num' :  {'type':'number'}
      },
      'required':['xtype', 'num'],
      'additionalProperties':false
    },
    'typetwo': 
    {
      'type': 'object',
      'properties': 
      {
        'xtype': {'type':'string', 'const':'typetwo'},
        'str' :  {'type':'string'}
      },
      'required':['xtype', 'str'],
      'additionalProperties':false
    }
  },
  'anyOf':
  [
     { '$ref': '#/definitions/typeone' },
     { '$ref': '#/definitions/typetwo' },
  ]
}

但是,如果我给它 json 失败,因为像这样的对象缺少强制性 属性:

{
  'xtype': 'typeone'
}

...JSON does not match any schemas from 'anyOf'. 错误 - 我可以看到原因是它不知道尝试匹配 xtype,而只是认为 'typeone' 的 xtype 无效并且看别人。

有没有更好的方法来做 anyOf,它将基于一个 属性 值(如 'switch')进行硬匹配,然后给出有关缺少其他强制属性的错误对象类型?

它变得更加冗长,但您可以使用 if/then 根据“xtype”切换验证 属性。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "allOf": [
    {
      "if": {
        "type": "object",
        "properties": {
          "xtype": { "const": "typeone" }
        },
        "required": ["xtype"]
      },
      "then": { "$ref": "#/definitions/typeone" }
    },
    {
      "if": {
        "type": "object",
        "properties": {
          "xtype": { "const": "typetwo" }
        },
        "required": ["xtype"]
      },
      "then": { "$ref": "#/definitions/typetwo" }
    }
  ],
  "definitions": {
    "typeone": {
      "type": "object",
      "properties": {
        "xtype": {},
        "num": { "type": "number" }
      },
      "required": ["num"],
      "additionalProperties": false
    },
    "typetwo": {
      "type": "object",
      "properties": {
        "xtype": {},
        "str": { "type": "string" }
      },
      "required": ["str"],
      "additionalProperties": false
    }
  }
}

只需对模型进行少量更改,您就可以使用 dependencies 获得更简单、更清晰的架构。您可以使用与类型名称相对应的 属性 而不是“xtytpe”​​ 属性。例如,{ "typeone": true }.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "dependencies": {
    "typeone": {
      "type": "object",
      "properties": {
        "typeone": {},
        "num": { "type": "number" }
      },
      "required": ["num"],
      "additionalProperties": false
    },
    "typetwo": {
      "type": "object",
      "properties": {
        "typetwo": {},
        "str": { "type": "string" }
      },
      "required": ["str"],
      "additionalProperties": false
    }
  }
}