JSON模式if-else条件复杂场景

时间:2019-03-30 10:52:39

标签: json jsonschema

    {
        "policyHolder": {
            "fullName": "A"
        },
        "traveller": [
            {
                "fullName": "B",
                "relationship": "Spouse"
            },
            {
                "fullName": "A",
                "relationship": "My Self"
            }
        ]
    }

在上面的json中,我要验证

  • if "relationship" = "My Self",然后fullName必须与fullName中的policyHolder匹配
  • relationship数组中必须存在字段traveller,否则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"
                ],
                }
            }
        }
    }```

2 个答案:

答案 0 :(得分:1)

这是您遇到最大麻烦的第一个要求。 JSON模式不支持针对实例中其他位置的数据进行数据验证。这是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提取到了自己的枚举定义中,但这确实是可选的。您可以将其内联,如果没有定义的关系集,甚至可以是不受限制的字符串。)

答案 1 :(得分:1)

当前无法使用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,则必须在代码中进行此验证或更改数据结构,以免不必要。