【问题标题】:JSON Schema oneOf for array options用于数组选项的 JSON Schema oneOf
【发布时间】:2019-08-07 11:27:02
【问题描述】:

我正在尝试对 JSON 有效负载具有“步骤”数组且其内容可能只是预定义的一组选项之一的场景进行建模,例如:

{ "steps": ["s0"] } 
or
{ "steps": ["s1"] }
or
{ "steps": ["s0", "s2"] }

如何在架构中对此进行建模?以下:

{
  "$id": "https://example.com/person.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",

  "title": "Payload",
  "type": "object",

  "properties": {
    "steps": {
      "type": "array",
      "oneOf": [
        ["s0"],
        ["s1"],
        ["s0", "s2"]
      ]
    }
  }
}     

失败,“读取架构时出现意外标记:StartArray.Path 'properties.steps.oneOf[0]'”

编辑

抱歉移动球门柱,我将我的问题简化为建议的解决方案适用于简化 版本但不是原版。更复杂的是,我需要 $ref 对象而不是 string 值...

示例输入:

{ "steps": [{"name": "S0"}] } 
or
{ "steps": [{"name": "S1"}] }
or
{ "steps": [{"name": "S1"}, {"name": "S2"}] }

与预期不匹配的架构(遵循 @EylM 的建议)

{
  "$id": "https://example.com/person.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Request",
  "type": "object",
  "properties": {
    "steps": {
      "type": "array",
      "oneOf": [
        {
          "const": [
            {"$ref": "#/definitions/s0"}
          ]
        },
        {
          "const": [
            {"$ref": "#/definitions/s1"}
          ]
        },
        {
          "const": [
            {"$ref": "#/definitions/s1"},
            {"$ref": "#/definitions/s2"}
          ]
        }
      ]
    }
  },
  "required": [
    "steps"
  ],
  "definitions": {
    "s0": {
      "type": "object",
      "properties": {"name": { "const": "S0" }}
    },
    "s1": {
      "type": "object",
      "properties": {"name": {"const": "S1" }}
    },
    "s2": {
      "type": "object",
      "properties": {"name": { "const": "S2" }}
      }
    }
}

使用此架构并输入 { "steps":[{"name": "s0"}] } 我得到 JSON 对来自 'oneOf' 的任何模式都有效

不管有什么价值,我都在使用https://www.jsonschemavalidator.net/ 进行实验。

【问题讨论】:

    标签: json jsonschema


    【解决方案1】:

    根据您的编辑更新了我的答案。以下 JSON 模式验证了问题中的所有 3 个条件,我假设 { "steps": [{"name": "S2"}, {"name": "S1"}] } 无效。如果我错了,请纠正我。

    {
      "$id": "https://example.com/person.schema.json",
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "Request",
      "type": "object",
      "properties": {
        "steps": {
          "type": "array",
          "anyOf": [
            {
              "maxItems": 1,
              "items": {
                "oneOf": [
                  {
                    "$ref": "#/definitions/s0"
                  },
                  {
                    "$ref": "#/definitions/s1"
                  }
                ]
              }
            },
            {
              "minItems": 2,
              "maxItems": 2,
              "items": [
                {
                  "$ref": "#/definitions/s1"
                },
                {
                  "$ref": "#/definitions/s2"
                }
              ]
            }
          ]
        }
      },
      "required": [
        "steps"
      ],
      "definitions": {
        "s0": {
          "type": "object",
          "properties": {
            "name": {
              "const": "S0"
            }
          }
        },
        "s1": {
          "type": "object",
          "properties": {
            "name": {
              "const": "S1"
            }
          }
        },
        "s2": {
          "type": "object",
          "properties": {
            "name": {
              "const": "S2"
            }
          }
        }
      }
    }
    

    如果您想通过 { "steps": [{"name": "S2"}, {"name": "S1"}] } 的验证,请使用另一个 anyOf 块,如下所示。

    {
        "minItems": 2,
        "maxItems": 2,
        "items": [
           {
              "$ref": "#/definitions/s2"
           },
           {
              "$ref": "#/definitions/s1"
           }
        ]
    }
    

    【讨论】:

      【解决方案2】:

      尝试使用枚举关键字。

      enum 关键字用于将值限制为一组固定值。 它必须是一个至少包含一个元素的数组,其中每个元素是 独一无二。

      json-schema - More info.

      在您的情况下,JSON 看起来像:

      {
        "$id": "https://example.com/person.schema.json",
        "$schema": "http://json-schema.org/draft-07/schema#",
      
        "title": "Payload",
        "type": "object",
      
        "properties": {
          "steps": {
            "type": "array",
            "oneOf": [
              {"enum": ["s1"]},
              {"enum": ["s0"]},
              {"enum": ["s1, s2"]}
            ]
          }
        }
      }  
      

      【讨论】:

      • 您建议的架构是有效的,但输入 { "steps" : ["s0"] } 我得到:Value ["s0"] is not defined in enum
      • 当您使用的是draft-7,而不是enum,您可以使用const
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 2017-06-24
      • 2014-03-01
      • 1970-01-01
      • 2014-09-20
      • 2022-11-18
      • 1970-01-01
      相关资源
      最近更新 更多