json-如何要求一个字段或另一个字段(或其他两个字段),但不是全部?

我在想出可以验证JSON是否包含以下内容的JSON模式时遇到了麻烦:

  • 仅一个字段
  • 仅另一个领域
  • (其他两个字段之一)

但如果存在多个则不匹配。

具体来说,我要

  • matchesFiles
  • matchesFiles
  • matchesFiles和/或doesntMatchFiles

进行验证,但我不想接受更多的验证。

这是到目前为止我得到的:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "required": [ "unrelatedA" ],
    "properties": {
    "unrelatedA": {
        "type": "string"
    },
    "fileNames": {
        "type": "array"
    },
    "copyAll": {
        "type": "boolean"
    },
    "matchesFiles": {
        "type": "array"
    },
    "doesntMatchFiles": {
        "type": "array"
        }
    },
    "oneOf": [
         {"required": ["copyAll"], "not":{"required":["matchesFiles"]}, "not":{"required":["doesntMatchFiles"]}, "not":{"required":["fileNames"]}},
         {"required": ["fileNames"], "not":{"required":["matchesFiles"]}, "not":{"required":["doesntMatchFiles"]}, "not":{"required":["copyAll"]}},
         {"anyOf": [
               {"required": ["matchesFiles"], "not":{"required":["copyAll"]}, "not":{"required":["fileNames"]}},
               {"required": ["doesntMatchFiles"], "not":{"required":["copyAll"]}, "not":{"required":["fileNames"]}}]}
    ]
} ;

这比我想要的要匹配。 我希望它符合以下所有条件:

{"copyAll": true, "unrelatedA":"xxx"}
{"fileNames": ["aab", "cab"], "unrelatedA":"xxx"}
{"matchesFiles": ["a*"], "unrelatedA":"xxx"}
{"doesntMatchFiles": ["a*"], "unrelatedA":"xxx"}
{"matchesFiles": ["a*"], "doesntMatchFiles": ["*b"], "unrelatedA":"xxx"}

但不符合:

{"copyAll": true, "matchesFiles":["a*"], "unrelatedA":"xxx"}
{"fileNames": ["a"], "matchesFiles":["a*"], "unrelatedA":"xxx"}
{"copyAll": true, "doesntMatchFiles": ["*b"], "matchesFiles":["a*"], "unrelatedA":"xxx"}
{"fileNames": ["a"], "matchesFiles":["a*"], "unrelatedA":"xxx"}
{"unrelatedA":"xxx"}

我猜想我很想念一些东西-我想知道它是什么。

user3486184 asked 2020-08-06T16:45:33Z
1个解决方案
85 votes

问题是“非”语义。 “不需要”并不表示“禁止包含”。 这只是意味着您不必为了验证该架构而添加它。

但是,您可以使用“ oneOf”以更简单的方式满足您的规范。 请记住,这意味着“只有这些模式之一可以验证”。 以下架构实现了您要解决的属性切换:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "required": [
        "unrelatedA"
    ],
    "properties": {
        "unrelatedA": {
            "type": "string"
        },
        "fileNames": {
            "type": "array"
        },
        "copyAll": {
            "type": "boolean"
        },
        "matchesFiles": {
            "type": "array"
        },
        "doesntMatchFiles": {
            "type": "array"
        }
    },
    "oneOf": [
        {
            "required": [
                "copyAll"
            ]
        },
        {
            "required": [
                "fileNames"
            ]
        },
        {
            "anyOf": [
                {
                    "required": [
                        "matchesFiles"
                    ]
                },
                {
                    "required": [
                        "doesntMatchFiles"
                    ]
                }
            ]
        }
    ]
}
jruizaranguren answered 2020-08-06T16:45:45Z
translate from https://stackoverflow.com:/questions/24023536/how-do-i-require-one-field-or-another-or-one-of-two-others-but-not-all-of-them