首页 > 解决方案 > 与“anyOf”匹配的 Json Schema

问题描述

我希望能够管理一个“对象”的 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根据一个属性值(如“开关”)进行硬匹配,然后给出关于缺少该对象类型的其他强制属性的错误?

标签: jsonjsonschema

解决方案


它变得更加冗长,但您可以使用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
    }
  }
}

推荐阅读