Json 架构 if/then 未按预期工作

Json Schema if/then not working as expected

我正在尝试验证一个简单的 json 架构,但我似乎无法做到这一点。我正在尝试将这段代码实现到 JsonSchema 中,但它没有正确验证。

代码:

if (field1 is "REAL") {
    then both attributes.A and attributes.B are present
    if (attributes.field2 is "true") {
        then attributes.C is also present
    }
}

我已将其转换为 JsonSchema,如下所示:

{
  "$schema": "https://json-schema.org/draft/2019-09/schema#",
  "properties": {
    "field1": {},
    "attributes": {
      "type": "object",
      "properties": {
        "field2": {
          "type": "string",
          "default": "false"
        }
      }
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "field1": {
            "enum": [
              "REAL"
            ]
          }
        }
      },
      "then": {
        "properties": {
          "attributes": {
            "$id": "#/properties/realAttributes",
            "type": "object",
            "title": "The Attributes Schema",
            "required": [
              "A",
              "B"
            ],
            "properties": {
              "A": {},
              "B": {},
              "C": {},
              "D": {},
              "field2": {}
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "field1": {
            "enum": ["REAL"]
          },
          "attributes": {
            "properties": {
              "field2": {
                "enum": ["true"]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "attributes": {
            "required": [
              "C"
            ]
          }
        }
      }
    }
  ]
}

allOf 中的第二个 if 验证工作不正常,我不明白为什么。当我通过 field1 而不是 field2 时它失败了。 Play with the failing implementation here.

我希望这会通过,但它报告了一个错误,指出缺少 C。失败案例:

{
  "field1": "REAL",
    "attributes": {
      "A": 4,
        "B": 5
    }
}

JSON 架构通过将架构(和子架构)应用于实例位置来工作。

条件关键字 if/then/else 通过将 if 的架构值应用于实例位置来工作,并根据结果应用 thenelse(如果提供) .

这里的关键是JSON模式是一种基于约束的语言,任何你不指定/约束的都是允许的。

让我们来看看你的 if 子模式,它没有像你预期的那样工作...

{
  "properties": {
    "field1": {
      "enum": ["REAL"]
    },
    "attributes": {
      "properties": {
        "field2": {
          "enum": ["true"]
        }
      }
    }
  }
}

让我们看看您在这里指定的内容。 但首先,让我们检查一下 properties 做了什么...

Validation succeeds if, for each name that appears in both the
instance and as a name within this keyword's value, the child
instance for that name successfully validates against the
corresponding schema.

https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02#section-9.3.2.1

在您的 if 子模式中,您说过,“如果 field1 存在,它应该是“REAL””和“如果对象有一个 属性 attributes,并且如果那个对象值有一个 属性 field2,那么它应该是 "true" ".

问题是,如果 field1 不存在,如果 attributes 不存在,那么子模式仍然会通过验证。

如果您需要 属性,则必须 require

让我们看看您添加了 required 关键字的架构...

{
  "$schema": "https://json-schema.org/draft/2019-09/schema#",
  "properties": {
    "field1": {},
    "attributes": {
      "type": "object",
      "properties": {
        "field2": {
          "type": "string",
          "default": "false"
        }
      }
    }
  },
  "allOf": [
    {
      "if": {
        "required": [
          "field1"
        ],
        "properties": {
          "field1": {
            "enum": [
              "REAL"
            ]
          }
        }
      },
      "then": {
        "properties": {
          "attributes": {
            "$id": "#/properties/realAttributes",
            "type": "object",
            "title": "The Attributes Schema",
            "required": [
              "A",
              "B"
            ],
            "properties": {
              "A": {},
              "B": {},
              "C": {},
              "D": {},
              "field2": {}
            }
          }
        }
      }
    },
    {
      "if": {
        "required": [
          "field1"
        ],
        "properties": {
          "field1": {
            "enum": [
              "REAL"
            ]
          },
          "attributes": {
            "required": [
              "field2"
            ],
            "properties": {
              "field2": {
                "enum": [
                  "true"
                ]
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "attributes": {
            "required": [
              "C"
            ]
          }
        }
      }
    }
  ]
}

游乐场:https://www.jsonschemavalidator.net/s/mAPFXugk

现在子模式也需要关键字,验证工作如您所愿。

如果您 运行 在 JSON 架构中使用条件语句时遇到问题,您可以通过将子架构更改为 false 来测试您的假设,例如 then 的值.您可以使用此技术来检查满足或不满足哪些条件。