有条件地确定字段的必需性

时间:2021-03-17 05:32:25

标签: json jsonschema

我需要从架构中的不同属性引用特定属性(示例中的 Kind)的子架构,然后对其实施更多条件。需要注意的重要一点是,我无法在定义 Kind 的地方进行更改,我需要从其他属性中引用它,然后在其上添加条件。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "Kind": {
      "$id": "#/properties/Kind",
      "type": "string",
      "enum": [
        "Foo",
        "Bar"
      ]
    }
  },
  "allOf": [
    {
      "if": {
        "$ref": "#/properties/Kind",
        "const": "Foo"
      },
      "then": {
        "required": [
          "MyField"
        ]
      }
    }
  ]
}

像下面这样的 json 对象应该无法通过验证,因为 MyField 属性不存在

{
  "Kind": "Foo"
}

我不想要以下解决方案,因为这只是一个简化版本,最终我想从另一个属性中引用 Kind 值。如果我遵循,那么 #/properties/Kind 将相对于我引用 Kind 的位置进行解释,因此它不会引用顶级的 Kind。我想要一个使用 $ref 和 $id 关键字的解决方案。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "Kind": {
      "$id": "#/properties/Kind",
      "type": "string",
      "enum": [
        "Foo",
        "Bar"
      ]
    }
  },
  "allOf": [
    {
      "if": {
       "properties": {"Kind":{
         "const":"Foo"
       }}
      },
      "then": {
        "required": [
          "MyField"
        ]
      }
    }
  ]
}

总而言之,假设我遵循 JSON 结构。最后一个 allOf 语句是我需要添加的。

- Kind ( enum of One,Two)
- Other
  - MyField
  - ConditionField
  - allOf ( which enforces the required-ness of MyField based on ConditionField)
  - allOf ( MyField should be not-required if Kind is One) 
[ To add this last conditional, I need to reference the value of Kind. 
I'm hoping providing $id to Kind and referring to it with $ref should be my approach, 
which doesn't seem to be working]
<块引用>

进一步总结一下,如果我们能够使用 $id 和 $ref 获得第一个片段,我会得到我的答案。

1 个答案:

答案 0 :(得分:0)

似乎存在一些误解,难以完全理解这里的问题,但经过编辑的问题的一部分足够有意义,我想我可以开始工作,我们可以根据需要迭代答案。< /p>

让我们从一些没有意义的事情开始,希望它有助于澄清可能的误解。

$ref 无法更改架构的行为。如果没有 $ref 你就不能做某事,那么你就不能通过引入 $ref 使架构以另一种方式表现。该规则的唯一例外是递归模式,它需要无限大且重复的模式而不使用 $ref

我不确定您想从 $id 获得什么,但可以肯定地说您不需要它。在任何情况下,$id 使用的问题都是无效的。锚点中不能有 /。即使它是有效的,它也是多余的,因为您可以使用相同的 JSON 指针引用该位置而无需锚点。

<块引用>

如果 Kind 为 One,则 MyField 不是必需的

我不确定“非必需”是指禁止还是可选。默认情况下,JSON Schema 中的所有内容都是可选的,所以如果您的意思是可选的,那么这里没有什么可做的。因此,我暂时假设您的意思是禁止。这就是它的样子。

{
  "type": "object",
  "properties": {
    "Kind": { "enum": ["One", "Two"] },
    "Other": {
      "type": "object",
      "properties": {
        "MyField": {}
      }
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "Kind": { "const": "One" }
        },
        "required": ["Kind"]
      },
      "then": {
        "properties": {
          "Other": {
            "not": { "required": ["MyField"] }
          }
        }
      }
    }
  ]
}