JSON schema validate oneOf two or allOf

2019-07-17 07:15发布

问题:

i want to validate following json schema, i am using Ajv npm package.

{
    "email": "xyzmail@gmail.com",
    "phone": "1112223334",
    "country_code": "91"
}

i want either email only, or phone and country_code only, or all of three properties should be there.

i have tried oneOf, allOf, anyOf also have tried nested of theme but in some conditions its working and in some condidions its not working.

i have tried following code

{
    "type": "object",
    "properties": {
        "email": {
            "type": "string",
            "format": "email",
            "maxLength": constants.LENGTHS.EMAIL.MAX
        },
        "phone": {
            "type": "string",
            "pattern": constants.REGEX.PHONE,
            "maxLength": constants.LENGTHS.PHONE.MAX
        },
        "country_code": {
            "type": "string",
            "pattern": constants.REGEX.COUNTRY_CODE,
            "maxLength": constants.LENGTHS.COUNTRY_CODE.MAX
        }
    },
    "anyOf": [
        {
            "required": ["email"],
        },
        {
            "required": ["phone", "country_code"],
        },
        {
            "required": ["email", "phone", "country_code"]
        },
    ],
    "additionalProperties": false

}

回答1:

You need:

"anyOf": [
    {
        "required": ["phone", "country_code"]
    },
    {
        "required": ["email"],
        "not": {
            "anyOf": [
                { "required": ["phone"] },
                { "required": ["country_code"] }
            ]
        }
    }
]

The first sub-schema allows for email both present and absent, which is what you want.

Using keyword "propertyNames" keyword that is added to JSON-schema draft-06 (to be published soon, available in Ajv 5.0.1-beta) you can make it a bit simpler (and easier to read):

"anyOf": [
    {
        "required": ["phone", "country_code"]
    },
    {
        "required": ["email"],
        "propertyNames": {"not": {"enum": ["phone", "country_code"] } }
    }
]

Or you can use custom keyword "prohibited" defined in ajv-keywords (see https://github.com/json-schema-org/json-schema-spec/issues/213):

"anyOf": [
    {
        "required": ["phone", "country_code"]
    },
    {
        "required": ["email"],
        "prohibited": ["phone", "country_code"]
    }
]


标签: json node.js ajv