【问题标题】:JSON Schema conditionnal required depending on value取决于值,需要 JSON Schema 条件
【发布时间】:2019-11-09 06:50:49
【问题描述】:

我的 JSON 验证有问题。我的页面中有 3 个链接的选择框,我需要验证以反映 UI 显示的内容。 3个选择是: - 范围:可以是ScopeNationalScopeRegionalScopeInternational - 国家:国家列表 - 地区:地区列表(“欧洲”、“亚洲”等)

在模式中,选择是具有两个属性的对象:“key”和“text”,都是字符串。

如果范围是“ScopeNational”,则需要“Country”和“Region”。如果范围是“ScopeRegional”,则只需要“Region”。最后,如果范围是“ScopeInternational”,则不需要“Country”或“Region”。

我用anyOfoneOfif-then-else 尝试了许多配置,但我无法实现 这是我尝试的最后一个架构,但没有成功:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$id": "http://example.com/root.json",
    "type": "object",
    "title": "Linked scope",
    "default": null,
    "properties": {

      "scope": {
        "$id": "#/properties/scope",
        "title": "Project scope",
        "$ref": "#/definitions/Scope"
      },
      "country": {
        "$id": "#/properties/country",
        "title": "Country",
        "$ref": "#/definitions/Choice"
      },
      "region": {
        "$id": "#/properties/region",
        "title": "Region",
        "$ref": "#/definitions/Choice"
      }
    },
    "oneOf": [
      {
        "properties": {
          "scope": {
            "properties": {
              "key": {
                "const": "ScopeNational"
              }
            }
          },
          "country": {
            "required": [
              "key",
              "text"
            ]
          },
          "region": {
            "required": [
              "key",
              "text"
            ]
          }
        }
      },
      {
        "properties": {
          "scope": {
            "properties": {
              "key": {
                "const": "ScopeRegional"
              }
            }
          },
          "region": {
            "required": [
              "key",
              "text"
            ]
          }
        }
      },
      {
        "properties": {
          "scope": {
            "properties": {
              "key": {
                "const": "ScopeInternational"
              }
            }
          }
        }
      }
    ],
    "required": [
      "scope"
    ],
    "definitions": {
      "Choice": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        },
        "required": [
          "key",
          "text"
        ]
      },
      "Scope": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "enum": [
              "ScopeNational",
              "ScopeRegional",
              "ScopeInternational"
            ]
          },
          "text": {
            "type": "string"
          }
        },
        "required": [
          "key",
          "text"
        ]
      }
    }
  }

谢谢!

【问题讨论】:

  • 能否给我们展示一个有效和无效的 JSON 示例?
  • @leadpony 绝对是 这将是有效的:json { "scope": { "key": "ScopeNational", "text": "National" }, "country": { "key": "France", "text": "France" }, "region": { "key": "Europe", "text": "Europe" } } 这不会:json { "scope": { "key": "ScopeNational", "text": "National" }, "country": { "key": null, "text": null }, "region": { "key": "Europe", "text": "Europe" } }

标签: json schema ajv


【解决方案1】:

我稍微修改了您的架构,如下所示。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "title": "Linked scope",
  "properties": {
    "scope": {
      "$id": "#/properties/scope",
      "title": "Project scope",
      "$ref": "#/definitions/Scope"
    }
  },
  "oneOf": [
    {
      "properties": {
        "scope": {
          "properties": {
            "key": {
              "const": "ScopeNational"
            }
          }
        },
        "region": {
          "$ref": "#/definitions/Choice"
        },
        "country": {
          "$ref": "#/definitions/Choice"
        }
      }
    },
    {
      "properties": {
        "scope": {
          "properties": {
            "key": {
              "const": "ScopeRegional"
            }
          }
        },
        "region": {
          "$ref": "#/definitions/Choice"
        },
        "country": {
          "$ref": "#/definitions/NullableChoice"
        }
      }
    },
    {
      "properties": {
        "scope": {
          "properties": {
            "key": {
              "const": "ScopeInternational"
            }
          }
        },
        "region": {
          "$ref": "#/definitions/NullableChoice"
        },
        "country": {
          "$ref": "#/definitions/NullableChoice"
        }
      }
    }
  ],
  "required": [
    "scope",
    "country",
    "region"
  ],
  "definitions": {
    "Choice": {
      "type": "object",
      "properties": {
        "key": {
          "type": "string"
        },
        "text": {
          "type": "string"
        }
      },
      "required": [
        "key",
        "text"
      ]
    },
    "NullableChoice": {
      "type": "object",
      "properties": {
        "key": {
          "type": ["string", "null"]
        },
        "text": {
          "type": ["string", "null"]
        }
      },
      "required": [
        "key",
        "text"
      ]
    },
    "Scope": {
      "type": "object",
      "properties": {
        "key": {
          "type": "string",
          "enum": [
            "ScopeNational",
            "ScopeRegional",
            "ScopeInternational"
          ]
        },
        "text": {
          "type": "string"
        }
      },
      "required": [
        "key",
        "text"
      ]
    }
  }
}

现在所有属性都是必需的,并且新定义 NullableChoice 已添加到架构中。请注意 null 是 JSON Schema 中的 stringnumber 之类的类型。

【讨论】:

  • 感谢您的回答,现在我知道我在哪里误解了 JSON 模式的工作原理(我是新手)。在我的最终 JSON 中,范围、国家和地区将始终存在,但键和文本将为空,具体取决于用户所做的选择。所以我想我应该添加/使用“字符串不为空”约束而不是必需的?
  • 抱歉耽搁了,它按预期工作,我将其标记为已解决。谢谢!
猜你喜欢
  • 2019-04-23
  • 1970-01-01
  • 2019-04-11
  • 1970-01-01
  • 2021-01-25
  • 2020-06-09
  • 1970-01-01
  • 1970-01-01
  • 2017-07-05
相关资源
最近更新 更多