Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json schema dynamic key validation

Facing an issue with schema validation.

schema :

{
    "type": "object",
    "$schema": "http://json-schema.org/draft-03/schema",
    "id": "#",
    "required": true,
    "patternProperties": {
        "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$": {
            "type": "object",
            "required": true,
            "properties": {
                "_from": {
                    "id": "_from",
                    "type": "string",
                    "required": true
                },
                "message": {
                    "type": "object",
                    "id": "message",
                    "properties": {
                        "detail": {
                            "type": "string",
                            "id": "detail",
                            "required": true
                        },
                        "from": {
                            "type": "string",
                            "id": "from",
                            "required": true
                        }
                    }
                }
            }
        }
    }
}

json :

{
    "[email protected]": {
        "_from": "[email protected]",
        "message": {
            "from": "[email protected]",
            "detail": "AnyonewanttomeetmeinParis"
        }
    },
    "[email protected]": {
        "_from": "[email protected]",
        "message": {
            "from": "[email protected]",
            "detail": "AnyonewanttomeetmeinParis"
        }
    }
}

Here the key email address is dynamic, somehow it doesn't validate regex for email validation.

Can you please advise me to correct the schema.

I am validating using : http://json-schema-validator.herokuapp.com/index.jsp

like image 398
suri babu Avatar asked Dec 30 '14 12:12

suri babu


People also ask

How do you validate a JSON Schema?

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 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.

What is the value of using JSON Schema for validation?

The primary strength of JSON Schema is that it generates clear, human- and machine-readable documentation. It's easy to accurately describe the structure of data in a way that developers can use for automated validation. This makes work easier for developers and testers, but the benefits go beyond productivity.


2 Answers

I see in your pattern that you seem to have forgotten to escape some characters or didn't do it correctly:

"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$"

and it causes the error that you can see when you hover the mouse over the link at the top of the validator:

enter image description here

it should be:

"^[A-Z0-9\\._%\\+-]+@[A-Z0-9\\.-]+\\.[A-Z]{2,6}$"

or without escaping the inner/class characters but I'd use the first pattern because I think its intention is clearer:

"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$"

You need to have two \ because the first \ is an escape for the second \. With a single one it wouldn't work because there is no escape sequence like \. or \+ in javascript. You want to have a \in the pattern itself.

However json schema patternProperties are case sensitive by default so you need to extend your email pattern by adding a-z to it:

"^[A-Za-z0-9\\._%\\+-]+@[A-Za-z0-9\\.-]+\\.[A-Za-z]{2,6}$"

(I didn't find any other way to make it case insensitive)

You also need to exclude any other property names by adding "additionalProperties": false next to the patternProperties or otherwise it catches everything else that does not match the pattern.

The working schema should then look like this:

{
    "type": "object", 
    "$schema": "http://json-schema.org/draft-03/schema", 
    "id": "#", 
    "required": true,     
    "patternProperties": {
        "^[A-Za-z0-9\\._%\\+-]+@[A-Za-z0-9\\.-]+\\.[A-Za-z]{2,6}$": {
            "type": "object", 
            "required": true, 
            "properties": {
                "_from": {
                    "id": "_from", 
                    "type": "string", 
                    "required": true
                }, 
                "message": {
                    "type": "object", 
                    "id": "message", 
                    "properties": {
                        "detail": {
                            "type": "string", 
                            "id": "detail", 
                            "required": true
                        }, 
                        "from": {
                            "type": "string", 
                            "id": "from", 
                            "required": true
                        }
                    }
                }
            }
        }
    }, 
    "additionalProperties": false
}

I've tested it on: http://jsonschemalint.com/

like image 167
t3chb0t Avatar answered Oct 10 '22 11:10

t3chb0t


Changed the schema as per draft 04 :

{
"type": "object", 
"$schema": "http://json-schema.org/draft-04/schema", 
"patternProperties": {
    "^[A-Za-z0-9\\._%\\+-]+@[A-Za-z0-9\\.-]+\\.[A-Za-z]{2,6}$": {
        "type": "object", 
        "properties": {
            "__from": {
                "type": "string"
            }, 
            "message": {
                "type": "object", 
                "properties": {
                    "from": {
                        "type": "string" 
                    },
                    "detail": {
                        "type": "string"
                    }
                },
                 "required": [ "from","detail"]
            }
        },
        "required": [ "__from","message"]
   }
}, 
"additionalProperties": false
}
like image 32
suri babu Avatar answered Oct 10 '22 12:10

suri babu