7

I'm trying to create json schema for a document where field values in some object should validate against a enum defined in another object in the same document.

More specifically, in the example below, I'd like to be able to define "properties" with id and values (I should be able to define different properties in different json files). Then "objects" should be able to refer to these properties, so that object.properties[i].id must match with id of one of the properties and object.properties[i].value must match with one of the enum values defined for that property.

{
    "properties": [
        {
            "id": "SIZE",
            "values": ["small", "medium", "big"]
        },
        {
            "id": "MATERIAL",
            "values": ["wood", "glass", "steel", "plastic"]
        },
        {
            "id": "COLOR",
            "values": ["red", "green", "blue"]
        }
    ],

    "objects": [
        {
            "name": "chair",
            "properties": [
                {
                    "id": "SIZE",
                    "value": "small"
                },
                {
                    "id": "COLOR",
                    "value": "red"
                }
            ],
        },
        {
            "name": "table",
            "properties": [
                {
                    "id": "MATERIAL",
                    "value": "wood"
                }
            ]
        }
    ]
}

I tried to create json schema to validate such structure, but got stuck with describing reference to inner fields of "property" object. I also looked into the standard and did not find a way to achieve the goal.

Is it possible to create a json schema which would validate my json files?

Community
  • 1
  • 1
Mikhail
  • 844
  • 8
  • 18

1 Answers1

5

There is a proposal for $data reference that almost allows to do it if you change your data structure a little bit to remove one level of indirection. It's is supported in Ajv (I am the author).

So if your data were:

{
    "properties": {
        "SIZE": ["small", "medium", "big"],
        "MATERIAL": ["wood", "glass", "steel", "plastic"],
        "COLOR": ["red", "green", "blue"]
    },
    "objects": {
        "chair": {
            "SIZE": "small",
            "COLOR": "red"
        },
        "table": {
            "MATERIAL": "wood"
        }
    }
}

then your schema could have been:

{
    "type": "object",
    "properties": {
        "properties": {
            "type": "object",
            "additionalProperties": {
                "type": "array",
                "items": { "type": "string" }
            } 
        },
        "objects": {
            "type": "object",
            "additionalProperties": {
                "type": "object",
                "properties": {
                    "SIZE": {"enum": {"$data": "3/properties/SIZE"}},
                    "MATERIAL": {"enum": {"$data": "3/properties/MATERIAL"}},
                    "COLOR": {"enum": {"$data": "3/properties/MATERIAL"}}
                }
            }
        }
    }
}

And it could be dynamically generated based on all list of possible properties.

With the data structure you have you either can use custom keywords if the validator supports them or implement some part of validation logic outside of JSON schema.

esp
  • 7,314
  • 6
  • 49
  • 79