首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用JsonSchema和$ref验证异构对象列表

用JsonSchema和$ref验证异构对象列表
EN

Stack Overflow用户
提问于 2019-03-14 16:59:24
回答 1查看 705关注 0票数 0

我已经看到了类似的not quite match this particular case问题的答案,所以如果我错过了一个相关的答案,我很抱歉。

我有一个异构的对象数组,我想验证它。这些对象在顶层具有相同的格式,但是子对象非常不同,只能通过每个子对象中的属性来标识。

问题映射为验证以下数据,尽管数组中有两种以上的对象类型:

代码语言:javascript
复制
{
  "heterogeneous_array": [{
      "arbitrary_name": "foobar",
      "params": {
        "aa": "foo",
        "ab": "bar"
      }
    },
    {
      "arbitrary_name": "barfoo",
      "params": {
        "ba": "baz",
        "bb": "bot"
      }
    }
  ]
}

我使用以下模式,它声称即使在“params”键下的对象无效时也会验证输入json。如何修复json模式?

代码语言:javascript
复制
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "heterogeneous_array": {
      "$ref": "#/definitions/heterogeneous_array"
    }
  },
  "definitions": {
    "heterogeneous_array": {
      "type": "array",
      "items": {
        "arbitrary_name": {
          "type": "string"
        },
        "params": {
          "oneOf": [{
              "$ref": "#/definitions/schema_a"
            },
            {
              "$ref": "#/definitions/schema_b"
            }
          ]
        },
        "required": ["arbitrary_name", "params"]
      }
    },
    "schema_a": {
      "properties": {
        "aa": {
          "type": "string"
        },
        "ab": {
          "type": "string"
        }
      },
      "additionalProperties": false,
      "required": ["aa", "ab"]
    },
    "schema_b": {
      "properties": {
        "ba": {
          "type": "string"
        },
        "bb": {
          "type": "string"
        }
      },
      "additionalProperties": false,
      "required": ["ba", "bb"]
    }
  }
}

提前谢谢你!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-14 19:45:35

第一件事是parametersarbitrary_name不是JSON关键字。我想你少了几个properties关键字。

试试这个:

代码语言:javascript
复制
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "heterogeneous_array": {
      "$ref": "#/definitions/heterogeneous_array"
    }
  },
  "definitions": {
    "heterogeneous_array": {
      "type": "array",
      "items": {
        "properties": {             // missing this
          "arbitrary_name": {
            "type": "string"
          },
          "params": {
            "oneOf": [{
                "$ref": "#/definitions/schema_a"
              },
              {
                "$ref": "#/definitions/schema_b"
              }
            ]
          }
        },
        "required": ["arbitrary_name", "params"]    // "arbitrary_name" was "name"
      }
    },
    "schema_a": {
      "properties": {             // was "parameters"
        "aa": {
          "type": "string"
        },
        "ab": {
          "type": "string"
        }
      },
      "additionalProperties": false,
      "required": ["aa", "ab"]
    },
    "schema_b": {
      "properties": {             // was "parameters"
        "ba": {
          "type": "string"
        },
        "bb": {
          "type": "string"
        }
      },
      "additionalProperties": false,
      "required": ["ba", "bb"]
    }
  }
}

其中还有一些我评论过的东西。

最后一件事情(修复您所拥有的)是次要的,应该注意,并且可能无论如何都得到您的JSON库的支持: JSON中的布尔值总是小写的(例如,false而不是False)。(它们实际上被定义为显式标记。)

问题中不清楚的是,foobar对象是否需要aaab参数,而barfoo对象是否需要babb参数。如果是这样的话,如果您使用的是草案6或更高版本,您可以做一些其他的事情。

草案6定义了一个const属性,您可以使用它来隔离特定属性的值,并在对象的其他部分强制执行子模式。使用它,您可以创建一种开关语句。

代码语言:javascript
复制
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "heterogeneous_array": {
      "$ref": "#/definitions/heterogeneous_array"
    }
  },
  "definitions": {
    "heterogeneous_array": {
      "type": "array",
      "items": {
        "oneOf": [
          {"$ref": "#/definitions/schema_a"},
          {"$ref": "#/definitions/schema_b"}
        ],
        "required": ["arbitrary_name", "params"]
      }
    },
    "schema_a": {
      "properties": {
        "arbitrary_name": {"const": "foobar"},
        "params": {
          "properties": {
            "aa": {
              "type": "string"
            },
            "ab": {
              "type": "string"
            }
          },
          "additionalProperties": false,
          "required": ["aa", "ab"]
        }
      }
    },
    "schema_b": {
      "properties": {
        "arbitrary_name": {"const": "barfoo"},
        "params": {
          "properties": {
            "ba": {
              "type": "string"
            },
            "bb": {
              "type": "string"
            }
          },
          "additionalProperties": false,
          "required": ["ba", "bb"]
        }
      }
    }
  }
}

这有点像一次重组,您将需要为您拥有的每个arbitrary_name值提供一个arbitrary_name

此外,如果您使用草案7,您也有if/then/else关键字,但我认为这并不能使这个用例变得更干净。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55168214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档