JSON 根据值需要有条件的架构

JSON Schema conditionnal required depending on value

我的 JSON 验证有问题。我的页面中有 3 个链接的 select 框,我需要验证以反映 UI 显示的内容。 3 select 是: - 范围:可以是 ScopeNationalScopeRegionalScopeInternational - 国家:国家名单 - 区域:区域列表("Europe"、"Asia" 等)

在架构中,select 是具有两个属性的对象:"key" 和 "text",都是字符串。

如果范围是 "ScopeNational",则需要 "Country" 和 "Region"。如果范围是 "ScopeRegional",则只需要 "Region"。最后,如果范围是 "ScopeInternational",则需要 "Country" 或 "Region" 的 none。

我用 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"
        ]
      }
    }
  }

谢谢!

我稍微修改了你的架构如下。

{
  "$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 类似。