【问题标题】:JSON Schema if-else condition complex scenarioJSON Schema if-else 条件复杂场景
【发布时间】:2019-03-30 10:52:38
【问题描述】:
    {
        "policyHolder": {
            "fullName": "A"
        },
        "traveller": [
            {
                "fullName": "B",
                "relationship": "Spouse"
            },
            {
                "fullName": "A",
                "relationship": "My Self"
            }
        ]
    }

在上面的json中,我想验证一下

  • if "relationship" = "My Self" 然后 fullName 必须匹配 policyHolder 中的 fullName
  • traveller数组中必须存在字段relationship,否则json无效

我尝试使用if-elseallOf 等创建一个 json 模式,但没有什么可以做这些验证但不能。 请帮忙!!

架构:

{
    "type": "object",
    "required": [
        "policyHolder",
        "traveller",
    ],
    "properties": {
        "policyHolder": {
            "$id": "#/properties/policyHolder",
            "type": "object",
            "required": [
                "fullName"
            ],
            "properties": {
                "fullName": {
                    "$id": "#/properties/policyHolder/properties/fullName",
                    "type": "string",
                }
            }
        },
        "traveller": {
            "$id": "#/properties/traveller",
            "type": "array",
            "minItems": 1,
            "items": {
                "$id": "#/properties/traveller/items",
                "type": "object",
                "properties": {
                    "fullName": {
                        "$ref": "#/properties/policyHolder/properties/fullName"
                    },
                    "relationship": {
                        "$id": "#/properties/traveller/items/properties/relationship",
                        "type": "string",
                    }
                },
                "required": [
                    "fullName",
                    "relationship"
                ],
                }
            }
        }
    }```

【问题讨论】:

    标签: json jsonschema


    【解决方案1】:

    这是您遇到最多麻烦的第一个要求。 JSON Schema 不支持根据实例中其他地方的数据验证数据。这是一个highly discussed topic,但还没有被采用。我建议你用一点代码来验证这一点。

    对于第二个,我建议您将一些子模式提取到定义中,而不是尝试使用 ID。如果您从其他文档中引用 ID 或使用短(如单字)ID,则 ID 通常更有益。将 ID 定义为其在文档中的位置是多余的;大多数处理器会自动处理这个问题。

    {
      "type": "object",
      "required": [
        "policyHolder",
        "traveller",
      ],
      "definitions": {
        "person": {
          "type": "object"
          "properties": {
            "fullName": {"type": "string"}
          },
          "required": ["fullName"]
        },
        "relationship": { "enum": [ ... ] }   // list possible relationships
      },
      "properties": {
        "policyHolder": { "$ref": "#/definitions/person" },
        "traveller": {
          "type": "array",
          "minItems": 1,
          "items": {
            "allOf": [
              { "$ref": "#/definitions/person" },
              {
                "properties": {
                  "relationship": { "$ref": "#/definitions/relationship" }
                },
                "required": ["relationship"]
              }
            ]
          }
        }
      }
    }
    

    (我将relationship 提取到它自己的枚举定义中,但这实际上是可选的。如果您没有定义的一组关系,您可以将其保留为内联,甚至是不受限制的字符串。)

    【讨论】:

      【解决方案2】:

      目前无法使用 JSON 架构完成此操作。所有 JSON Schema 关键字一次只能对一个值进行操作。有一个添加 $data 关键字的建议可以进行这种验证,但我认为它不太可能被采用。 $data 会像 $ref 一样工作,只是它引用正在验证的 JSON,而不是引用架构。

      以下是使用$data 解决问题的方法。

      {
        "type": "object",
        "properties": {
          "policyHolder": {
            "type": "object",
            "properties": {
              "fullName": { "type": "string" }
            }
          },
          "traveler": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "fullName": { "type": "string" },
                "relationship": { "type": "string" }
              },
              "if": {
                "properties": {
                  "relationship": { "const": "My Self" }
                }
              },
              "then": {
                "properties": {
                  "fullName": { "const": { "$data": "#/policyHolder/fullName" } }
                }
              }
            }
          }
        }
      }
      

      如果没有$data,您将不得不在代码中进行此验证或更改您的数据结构,这样就没有必要了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-17
        • 1970-01-01
        相关资源
        最近更新 更多