简体   繁体   中英

If condition with a relative ref using JSON schema draft 7

I would like to use json schema to combine relative JSON pointer references, with a $ref schema, when I am introducing a conditional if / then statement.

In this case I would like to require that:

  • If system = Phone then require usePhone element
  • If system = Email then require useEmail element

The schema is generating an error when I use it to validate - I suspect the if -> $ref / enum code is the cause of the issue. The json-schema documentation suggests nesting required constant / enum values inside the defined element but I am unsure how to do this when my element is a $ref location, eg:

https://json-schema.org/understanding-json-schema/reference/conditionals.html

"if": {
    "properties": { "country": { "const": "United States of America" } }
  }

The need for a relative schema is because the instance of ContactPoint is used in multiple locations in the combined schema.

References:

Example:

Thanks!

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "id": "characteristic.entity.json",
    "title": "characteristic.entity.schema.1.0",
    "description": "Characteristic Objects Json Schema",
    "definitions": {
        "ContactPoint": {
            "title": "ContactPoint",
            "additionalProperties": true,
            "properties": {
                "id": {
                    "description": "",
                    "$ref": "primitive.entity.json#/definitions/string"
                },
                "type": {
                    "description": "The type of Contact.",
                    "enum": [
                        "Alternative",
                        "Primary"
                    ]
                },
                "system": {
                    "description": "Telecommunications form for contact point - what communications system is required to make use of the contact.",
                    "enum": [
                        "Phone",
                        "Email",
                        "other"
                    ]
                },
                "value": {
                    "description": "",
                    "$ref": "primitive.entity.json#/definitions/string"
                },
                "usePhone": {
                    "description": "Identifies the purpose of a Phone contact point.",
                    "enum": [
                        "Alternate",
                        "Business - Direct",
                        "Business - Main",
                        "Home",
                        "Mobile",
                        "Work"
                    ]
                },
                "useEmail": {
                    "description": "Identifies the purpose of an Email contact point.",
                    "enum": [
                        "Person",
                        "Work",
                        "Business"
                    ]
                }
            },
            "allOf": [
                {
                    "if": {
                        "$ref": "1/system",
                        "enum": [
                            "Phone"
                        ]
                    },
                    "then": {
                        "required": [
                            "usePhone"
                        ]
                    }
                },
                {
                    "if": {
                        "$ref": "1/system",
                        "enum": [
                            "Email"
                        ]
                    },
                    "then": {
                        "required": [
                            "useEmail"
                        ]
                    }
                }
            ]
        }
    }
}

Change your "id" keywords to "$id" -- the name of that keyword changed after JSON Schema draft 4.

As @Relequestual said, you can't have sibling keywords to $ref in drafts 7 or earlier, so you should wrap the $ref in an allOf (ie "allOf": [ { "$ref": ... } ] .

If you are using draft-2019-09, you should rename definitions to $defs .

Also, you can't use relative JSON pointers in $ref , so a ref like "1/system" will not resolve to anything (given what you have posted here). So change that ref to #/definitions/ContactPoint/properties/system and it should find the right position in the schema.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM