JSON 模式 - 只允许 属性 的特定枚举值并拒绝其余的

JSON Schema - Allow only specific enum values for a property and reject the rest

假设我有以下 JSON 我想验证。

[
   {
      "UpStatus":"Closed"
   },
   {
      "UpStatus":"Open"
   }
]

我希望 json 只有在数组中至少有一个 'UpStatus' 定义为 'Open' 或 'Locked' 时才能通过验证。

如果在数组中找不到 'UpStatus' 设置为 'Open' 或 'Locked',并且设置为任意的其他东西,比如“关闭”,我想要验证失败。

我修改了 anyOf 并提出了以下架构。

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array",
  "items": [
    {
      "type": "object",
      "properties": {
        "UpStatus": {
          "type": "string"
        }
      },
      "minItems": 1,
      "anyOf": [
        {
          "properties": {
            "UpStatus": {
              "const": "Open"
            }
          },
          "required": [
            "UpStatus"
          ]
        },
        {
          "properties": {
            "UpStatus": {
              "const": "Locked"
            }
          },
          "required": [
            "UpStatus"
          ]
        }
      ]
    }
  ]
}

上面不能正常工作,因为它允许下面的通过,我认为它应该无法验证。

[
  {
    "UpStatus": "Closed"
  },
  {
    "UpStatus": "Closed"
  }
]

我用 json 模式玩了很长时间,查看了示例并阅读了一些文档,但无法让它工作。任何帮助表示赞赏。谢谢。

在上面的架构中,您将“minItems”关键字放在“items”中,这什么都不做——它需要与“items”相邻。但是使用“items”也意味着 all items 必须匹配,而不仅仅是一个。

改为使用“包含”:

{
  "type: "array",
  "contains": {
    "type": "object",
    "required": ["UpStatus"],
    "properties": {
      "UpStatus": {
        "enum": ["Open","Locked"],
      }
    }
  }
}

翻译:数据必须是一个数组,其中至少一个元素必须是一个对象,该对象的 属性“UpStatus”的值为“Open”或“Locked”。

您可能希望数组中的所有项目都符合特定的内容,在这种情况下,您可以使用“项目”来指定。 “项目”和“包含”之间的区别在于“项目”模式必须匹配 所有 项,而“包含”模式只需匹配一个。

然而,“包含”在规范的草案 4 版本中不可用。你有机会升级吗? There is a list of implementations in various languages here. Alternatively, you can simulate the "contains" keyword with "not": { "items": { "not": { ... schema ... } } } (courtesy Jason Desrosiers).


附录:当我评估你的模式和数据时,它没有通过,而是产生了这些错误,所以你的实现可能有问题(或者你粘贴了一些东西):

{
  "errors" : [
    {
      "error" : "value does not match",
      "instanceLocation" : "/0/UpStatus",
      "keywordLocation" : "/items/0/anyOf/0/properties/UpStatus/const"
    },
    {
      "error" : "not all properties are valid",
      "instanceLocation" : "/0",
      "keywordLocation" : "/items/0/anyOf/0/properties"
    },
    {
      "error" : "value does not match",
      "instanceLocation" : "/0/UpStatus",
      "keywordLocation" : "/items/0/anyOf/1/properties/UpStatus/const"
    },
    {
      "error" : "not all properties are valid",
      "instanceLocation" : "/0",
      "keywordLocation" : "/items/0/anyOf/1/properties"
    },
    {
      "error" : "no subschemas are valid",
      "instanceLocation" : "/0",
      "keywordLocation" : "/items/0/anyOf"
    },
    {
      "error" : "not all items are valid",
      "instanceLocation" : "",
      "keywordLocation" : "/items"
    }
  ],
  "valid" : false
}