Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json schema to validate object's values against content of another object

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?

like image 222
Mikhail Avatar asked Nov 22 '16 12:11

Mikhail


People also ask

How does JSON Schema validate JSON data?

The simplest way to check if JSON is valid is to load the JSON into a JObject or JArray and then use the IsValid(JToken, JsonSchema) method with the JSON Schema. To get validation error messages, use the IsValid(JToken, JsonSchema, IList<String> ) or Validate(JToken, JsonSchema, ValidationEventHandler) overloads.

Can we validate JSON with schema?

JSON Schema is a powerful tool. It enables you to validate your JSON structure and make sure it meets the required API. You can create a schema as complex and nested as you need, all you need are the requirements. You can add it to your code as an additional test or in run-time.

What is a JSON Schema validator?

JSON Schema validation asserts constraints on the structure of instance data. An instance location that satisfies all asserted constraints is then annotated with any keywords that contain non-assertion information, such as descriptive metadata and usage hints.

What is JSON Schema additionalProperties?

The additionalProperties keyword is used to control the handling of extra stuff, that is, properties whose names are not listed in the properties keyword or match any of the regular expressions in the patternProperties keyword. By default any additional properties are allowed.


Video Answer


1 Answers

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.

like image 146
esp Avatar answered Oct 04 '22 01:10

esp