如何根据另一个 属性 的值设置模式对象的类型?

how to set the type of a schema object based on the value of another property?

我有一个对象(来自第 3 方,所以我无法更改它)有一个名为 "key" 的 属性,另一个名为 "value" 的 属性 ] 是可选的,它的类型取决于 "key" 属性.

的值

例如:
如果key是"comment",value的类型是{"Text":"commentValue"}.
如果key是"offset",那么value的类型就是{"seconds":int}.
如果key是"weather",那么value的类型就是{"value": Enum["sun", "clouds", "rain"...]}

此外,一些键没有值属性,所以模式应该禁止它与这些键一起出现。这些键之一是 "standby"(正如您在下面我当前的尝试中看到的那样)

我试过操作 中的代码示例,但无法正常工作。

我目前正在尝试使用 Newtonsoft's JSON Schema Validator 根据我的模式尝试验证输出 json - 但我似乎无法正确定义 "value" 属性 .

到目前为止,这是我的代码:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "TestOptionalObject",
    "type": "object",
    "additionalProperties": false,
    "required": [
        "test"
    ],
    "properties": {
        "test": {
            "$ref": "#/definitions/test"
        }
    },
    "definitions": {
        "test": {
            "type": "object",
            "additionalProperties": false,
            "required": [
                "key",
            ],
            "properties": {
                "key": {
                    "type": "string",
                    "enum": ["standby", "comment", "offset"]
                },
                "value" : {
                    "if": {
                        "properties": {
                          "key": {"enum": ["comment"]}
                        }
                    },
                    "then": { 
                        "$ref": "#/definitions/commentValue"
                    },
                    "if": {
                        "properties": {
                          "key": {"enum": ["offset"]}
                        }
                    },
                    "then": { 
                        "$ref": "#/definitions/offsetValue"
                    }
                }
            }
        },
        "commentValue" : {
            "type": "object",
            "additionalProperties": false,
            "required": [
                "text",
            ],
            "properties": {
                "text" : {"type" : "string"}
            }
        },
        "offsetValue" : {
            "type": "object",
            "additionalProperties": false,
            "required": [
                "seconds",
            ],
            "properties": {
                "seconds" : {
                    "type": "integer",
                    "format": "int32"
                }
            }
        }
    }
}

这是我收到的错误消息:

JSON does not match schema from 'then'. Schema path: #/definitions/offsetValue/then

Property 'text' has not been defined and the schema does not allow additional properties. Schema path: #/definitions/offsetValue/additionalProperties

Required properties are missing from object: seconds. Schema path: #/definitions/offsetValue/required

Json 个验证示例:

应该失败:

{
  "test": {
    "key": "comment",
      "value": {"seconds":12}
  }
}


{
  "test": {
    "key": "standby",
     "value": {"asdf":12}
  }
}

应该通过:

{
  "test": {
    "key": "comment",
     "value": {"text":"comment text"}
  }
}


{
  "test": {
    "key": "offset",
     "value": {"seconds":12}
  }
}

我已经更改了您的 JSON 模式,因此它可以满足您的期望,除了 standby 的形式键,因为您没有将其包含在您的模式中,您应该能够复制我创建的模式是根据需要添加新密钥。

您遇到的主要问题是关于放置 if/then/else 关键字的错误假设。它们是应用程序关键字,因此必须应用于您正在检查其条件的对象,而不是 properties 键值。因为您在值为 value 的对象中使用了 if/then/else,所以您将 if/then/else 应用于 value 的值而不是 test

您需要将 if 应用到 test 以获得检查 key 属性 值的正确范围。

这是生成的固定架构:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "TestOptionalObject",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "test"
  ],
  "properties": {
    "test": {
      "$ref": "#/definitions/test"
    }
  },
  "definitions": {
    "test": {
      "type": "object",
      "required": [
        "key"
      ],
      "properties": {
        "key": {
          "type": "string",
          "enum": [
            "standby",
            "comment",
            "offset"
          ]
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "key": {
                "const": "comment"
              }
            }
          },
          "then": {
            "properties": {
              "value": {
                "$ref": "#/definitions/commentValue"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "key": {
                "const": "offset"
              }
            }
          },
          "then": {
            "properties": {
              "value": {
                "$ref": "#/definitions/offsetValue"
              }
            }
          }
        }
      ]
    },
    "commentValue": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "text"
      ],
      "properties": {
        "text": {
          "type": "string"
        }
      }
    },
    "offsetValue": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "seconds"
      ],
      "properties": {
        "seconds": {
          "type": "integer",
          "format": "int32"
        }
      }
    }
  }
}

如果您需要更多帮助,请随时使用 http://json-schema.org 网站上的讨论 link 加入 JSON Schema slack。