首页 > 解决方案 > 'if, then and else' 关键字可以应用在对象的属性中还是严格保留在外部?

问题描述

https://json-schema.org/understanding-json-schema/reference/conditionals.html URL 中提到的所有示例都具有对象属性之外的“if、then 和 else”条件。我只是想知道它是否可以在属性中设置并仍然遵循标准?

{
  "type": "object",
  "properties": {
    "street_address": {
      "type": "string"
    },
    "country": {
      "enum": ["United States of America", "Canada"]
    }
  },
  "if": {
    "properties": { "country": { "const": "United States of America" } }
  },
  "then": {
    "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
  },
  "else": {
    "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
  }
}

可以这样做吗?

{
  "type": "object",
  "properties": {
    "street_address": {
      "type": "string"
    },
    "country": {
      "enum": ["United States of America", "Canada"]
    },
    "if": {
      "properties": { "country": { "const": "United States of America" } }
    },
    "then": {
      "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
    },
    "else": {
     "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
    }
  }
}

我在网上尝试了 JSON-schema lint,它没有引发任何错误,但是我不知道它的实现,因此不太确定语法是否与建议的 draft-7 匹配。

在对象的属性中这样做的动机是:特别是在大型模式文件中,如果我可以定义一个属性,其值有条件地依赖于它旁边的一些其他属性,那感觉会更好。而不是首先完成所有属性,然后在属性之外单独应用条件。

对编程非常陌生 - 如果这是一个非常不正确的问题,请原谅我。谢谢你。

标签: jsonschema

解决方案


所有关键字,包括//if都可以出现在任何模式中。关键字的值被定义为一个对象,其值为模式。因此,关键字不能用作 的子项,但可以用于其中一个值。thenelsepropertiesproperties

如果你做这样的事情......

{
  "type": "object",
  "properties": {
    "street_address": { "type": "string" },
    "country": { "enum": ["United States of America", "Canada"] },
    "if": {
      "properties": { "country": { "const": "United States of America" } }
    },
    "then": {
      "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
    },
    "else": {
     "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
    }
  }
}

它正在描述一个对象,例如...

{
  "street_address": "123 Fake St",
  "country": "United States of America",
  "if": { "country": "United States of America" },
  "then": { "postal_code": "90000" },
  "else": { "postal_code": "A0A 0A0" }
}

请注意,“if”、“then”、“else”被理解为属性名称,而不是关键字。同样,这是因为 的值properties不是模式,它是一个对象,其值是模式。该架构恰好是一个有效的架构,它只是没有按照您的预期去做。

因此你可以做这样的事情......

{
  "type": "object",
  "properties": {
    "street_address": { "type": "string" },
    "country": { "enum": ["United States of America", "Canada"] },
    "postal_code": {
      "if": { ... },
      "then": { ... },
      "else": { ... }
    }
  }
}

在这种情况下,它会将if/ then/识别else为关键字,但没有办法编写此条件来执行您正在尝试执行的操作。正如您所看到的示例所做的那样,您必须将其放在顶层。


推荐阅读