json schema validate data dependency between peer values

4,057 views
Skip to first unread message

Andy Heath

unread,
Jul 24, 2012, 2:50:59 PM7/24/12
to json-...@googlegroups.com
I need to validate instances like this

[
    {
        "property" : "colour",
        "condition": true,
        "value": "red"
    },
    {
        "property": "screenwidth",
        "condition": false,
        "value": "1024"
    }
]

This is one instance (i.e. it contains 0..* objects of the same form).

Each value of "value" is from a vocabulary that depends on the value ot "property" - so screenwidth would have a different set of possible valid values from colour.

After banging my head on this for a couple of hours I can't see a way to do it within json schema. Help please.

andy

Eric Stob

unread,
Jul 24, 2012, 3:02:16 PM7/24/12
to json-...@googlegroups.com
Have one schema per property string

Use a map of property string to schema to select the schema to use to validate the item.

I do it like this (in coffeescript)

report = env.validate longline, longitudeschema[longline.log_type]

so my longitudeschema looks like  "type1" : schema1 , "type2" : schema2 etc, and longline.log_type contains "type1" or "type2"




andy

--
You received this message because you are subscribed to the Google Groups "JSON Schema" group.
To view this discussion on the web visit https://groups.google.com/d/msg/json-schema/-/jfqVQ9mJ_wMJ.
To post to this group, send email to json-...@googlegroups.com.
To unsubscribe from this group, send email to json-schema...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/json-schema?hl=en.

Andy Heath

unread,
Jul 24, 2012, 3:12:27 PM7/24/12
to json-...@googlegroups.com
I would, but I can't change even the names of the fields - for example "property" must be "property".
i think its a crazy model as its wasteful - all that repetition of each field name (property, condition, value).  I would use the value of "property" as the field name but that's outlawed - I'm stuck with this form.

If I could go outside of json I'd  use some sed to swap the fields over, validate it then swap them back but this I can't do either (it would be pretty slow too).  So I'm stuck with this crazy data model. I'm fairly new to json and json-schema but it looks impossible to me to do with json-schema because the scope is all wrong (i.e. its a bad data model).  Can anyone confirm its not possible in this form ?  - if I'm correct I'll argue to change the model to get rid of the redundancy.

andy

Eric Stob

unread,
Jul 24, 2012, 3:39:05 PM7/24/12
to json-...@googlegroups.com
Doesn't matter what the determinant field is called - adjust your logic accordingly.  (mine is called log_type, yours is called property, doesn't matter what it's called)

Sent from my iPhone
--
You received this message because you are subscribed to the Google Groups "JSON Schema" group.
To view this discussion on the web visit https://groups.google.com/d/msg/json-schema/-/_HHTBmN2idwJ.

Eric Stob

unread,
Jul 24, 2012, 3:40:23 PM7/24/12
to json-...@googlegroups.com
It is absolutely possible as I believe my example made clear.

Sent from my iPhone

On Jul 24, 2012, at 12:12 PM, Andy Heath <andyheat...@googlemail.com> wrote:

--

Christian Autermann

unread,
Jul 24, 2012, 4:00:31 PM7/24/12
to json-...@googlegroups.com
What about creating a schema for every property-type (and extending a base property)?

{
"propertybase": {
"id": "propertybase",
"type": "object",
"properties": {
"property": { "type": "string" },
"condition": { "type": "boolean" },
"value": { "type": "any" }
}
},
"type": "array",
"items": [
{
"extends": "#propertybase",
"properties": {
"property": { "enum": [ "colour" ] },
"value": { "type": "string", "enum": [ "red", "blue" ] }
}
}, {
"extends": "#propertybase",
"properties": {
"property": { "enum": [ "screenwidth" ] },
"value": { "type": "integer" }
}
}
]
}

--Christian

Andy Heath

unread,
Jul 24, 2012, 4:09:29 PM7/24/12
to json-...@googlegroups.com

It is absolutely possible as I believe my example made clear.

Eric, would you be able to post a little bit of json-schema to show me more clearly. I don't speak coffee-script (yet) and am very new to json.  I just need to figure out the structure then I can fill in the rest.

For example suppose the following instance (I removed condition as its not relevant to this)

[
    {
        "property" : "colour",

        "value": "red"
    },
    {
        "property": "screenwidth",
        "value": "1024"
    }
]

And suppose the vocab for "value" when "property" has a value of "colour" is ["red", "blue", "green"] and that when "property" has a value of "screenwidth" then "value" must match the regex "^1[0-9]*$" (which is simplistic for a screensize but its the structure I'm after - even better, just make it an integer instead).

Could you post a little piece of json-schema to do this validation ? (not javascript, just json-schema - I'm using an online validator) so I can see its structure because I just can't see how to structure it with this dependency.

Thanks for your help

andy


Sent from my iPhone


I would, but I can't change even the names of the fields - for example "property" must be "property".
i think its a crazy model as its wasteful - all that repetition of each field name (property, condition, value).  I would use the value of "property" as the field name but that's outlawed - I'm stuck with this form.

If I could go outside of json I'd  use some sed to swap the fields over, validate it then swap them back but this I can't do either (it would be pretty slow too).  So I'm stuck with this crazy data model. I'm fairly new to json and json-schema but it looks impossible to me to do with json-schema because the scope is all wrong (i.e. its a bad data model).  Can anyone confirm its not possible in this form ?  - if I'm correct I'll argue to change the model to get rid of the redundancy.

andy

--
You received this message because you are subscribed to the Google Groups "JSON Schema" group.
To view this discussion on the web visit https://groups.google.com/d/msg/json-schema/-/_HHTBmN2idwJ.
To post to this group, send email to json-...@googlegroups.com.
To unsubscribe from this group, send email to json-schema+unsubscribe@googlegroups.com.

Andy Heath

unread,
Jul 24, 2012, 4:20:15 PM7/24/12
to json-...@googlegroups.com
Christian, I think you may have solved it for me, thankyou. My response to Eric was cross-posted with
your response which I hadn't read then.

One aspect I don't understand - is it the use of "extends" that excludes the instances where they just match


"property": { "type": "string" },
"condition": { "type": "boolean" },
"value": { "type": "any" }

Also, is using "extends" the only way to deal with this kind of dependency ? I read that not all schema-validation applications implement "extends"

Thanks again

andy

andy

Eric Stob

unread,
Jul 24, 2012, 4:53:59 PM7/24/12
to json-...@googlegroups.com
Here is an example.

schema.json

{
  "description":"Longitude JSON schemas",
  "version":"longitude-1.01",
  "query" : 
  {
    "name":"query",  
    "properties":
    {
      "log_type":
      {
        "type":"string",
        "required":"true",
        "pattern":"^query$"
      },
      "time":
      {
        "type":"integer",
        "description":"Unix time of the transaction",
        "required":true,
        "minimum":0
      }
    }
  },
  "toolbar":
  {
    "name": "toolbar",
    "properties":
    {
      "log_type":
      {
        "type":"string",
        "required":true,
        "pattern":"^toolbar$"
      },
      "line_id":  
      {
        "type":"string",
        "description":"Unique identifier of the transaction",
        "required":true,
        "pattern":"^(0x)?[0-9a-fA-F]+$"
      }
    }
  }
}

instance.json
[
  { "log_type" : "query", "time" : 1253126 },
  { "log_type" : "toolbar", "line_id" : "0x0fed5b" },
  { "log_type" : "query", "line_id" : "0x0fed5b" }  
]
( the first two should pass; the third one should fail due to lacking the required "time" field )

validate.coffee
util       = require "util"
filesystem = require "fs"
JSV        = require ("JSV").JSV

env = JSV.createEnvironment()

filesystem.readFile "schema.json", (err, data) ->
  schema = JSON.parse data.toString()
  filesystem.readFile "instance.json", (err, data) ->
    instance = JSON.parse data.toString()
    for line in instance
      report = env.validate line, schema[line.log_type]
      console.log line
      console.log report


To view this discussion on the web visit https://groups.google.com/d/msg/json-schema/-/c_lIcMHJEjkJ.

To post to this group, send email to json-...@googlegroups.com.
To unsubscribe from this group, send email to json-schema...@googlegroups.com.

Andy Heath

unread,
Jul 24, 2012, 5:09:19 PM7/24/12
to json-...@googlegroups.com

Thankyou Eric, Thankyou Christian, both of great help.

Christian - I can't get your example to validate those instances using

http://jsonschemalint.com/

No idea why - is there a level of "object" missing ?

Eric - thankyou very much for this very clear example which I will play with in the am.
Computers schomuters, who loves them ..

andy

Francis Galiegue

unread,
Jul 24, 2012, 5:17:34 PM7/24/12
to json-...@googlegroups.com
On Tue, Jul 24, 2012 at 9:02 PM, Eric Stob <eric...@blekko.com> wrote:
> Have one schema per property string
>
> Use a map of property string to schema to select the schema to use to
> validate the item.
>
> I do it like this (in coffeescript)
>
> report = env.validate longline, longitudeschema[longline.log_type]
>
> so my longitudeschema looks like "type1" : schema1 , "type2" : schema2 etc,
> and longline.log_type contains "type1" or "type2"
>

Which is not a valid way to call to JSON Schemas, I hope you are aware of that?

--
Francis Galiegue, fgal...@gmail.com
"It seems obvious [...] that at least some 'business intelligence'
tools invest so much intelligence on the business side that they have
nothing left for generating SQL queries" (Stéphane Faroult, in "The
Art of SQL", ISBN 0-596-00894-5)

Eric Stob

unread,
Jul 24, 2012, 6:02:16 PM7/24/12
to json-...@googlegroups.com
What do you mean "not valid"?
It works great, I tested extensively in production code.

Sent from my iPhone
> --
> You received this message because you are subscribed to the Google Groups "JSON Schema" group.

Christian Autermann

unread,
Jul 24, 2012, 9:00:28 PM7/24/12
to json-...@googlegroups.com
I think the validator is not capable of "extends" or "$ref". At least
when I tried it some time ago and it didn't get it to work (and the
error messages are not really helpful). By pasting the referenced
schema to the appropriate positions the validation was successful. (It
also may be that I am not able to define decent references :))

Of course you can do it without any references to accomplish
compatibility to all validators, but the schema will become quite
redundant. This one will validate your instance (I tested it with the
validator):

{
"type": "array",
"items": [
{
"type": "object",
"properties": {
"property": {
"type": "string",
"required": true,
"enum": [ "colour" ]
},
"condition": {
"required": true,
"type": "boolean"
},
"value": {
"required": true,
"type": "string",
"enum": [ "red", "blue", "green" ]
}
}
},
{
"type": "object",
"properties": {
"property": {
"required": true,
"type": "string",
"enum": [ "screenwidth" ]
},
"condition": {
"required": true,
"type": "boolean"
},
"value": {
"required": true,
"type": [ "integer", "string" ],
"pattern": "^1[0-9]*$"
}
}
}
]
}

Regarding the previous schema: it won't allow instances that only
match the base property as extends implies that the instance has to
obey the extended and the actual schema (it is some kind of
conjunction).

--Christian

2012/7/24 Andy Heath <andyheat...@googlemail.com>:
>>>> json-schema...@googlegroups.com.
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/json-schema?hl=en.
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "JSON Schema" group.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msg/json-schema/-/c_lIcMHJEjkJ.
>>>
>>> To post to this group, send email to json-...@googlegroups.com.
>>> To unsubscribe from this group, send email to
>>> json-schema...@googlegroups.com.
>>> For more options, visit this group at
>>> http://groups.google.com/group/json-schema?hl=en.
>>
>>
> --
> You received this message because you are subscribed to the Google Groups
> "JSON Schema" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/json-schema/-/kOIY3PbnUhcJ.
>
> To post to this group, send email to json-...@googlegroups.com.
> To unsubscribe from this group, send email to
> json-schema...@googlegroups.com.

Andy Heath

unread,
Jul 25, 2012, 1:57:17 AM7/25/12
to json-...@googlegroups.com, aute...@uni-muenster.de
Thankyou Christian. But ..
This is tuple typing ?
My problem with it is the ordering requirement it imposes - for example the
instance won't validate if the objects in the array are reversed in order :-( sigh ..

With that validator referencing does work (I have schemas that use "$ref" : "an-id-value" which work fine).
I tried also "extends" : { "$ref" : "an-id-value"} with your suggested solution, in line with
some threads around on this (though they may be referring to draft 2 of the specification) but no joy there. Maybe this validator implements "$ref" but not "extends" - however, the code behind it is jsv - does jsv implement "extends" ?
By the way - the aesthete in me likes the clean structure of your "extends" solution a lot.

So will this work if I change the tuple typing so its not an array of schemas but an array object with schemas inside (in the schema, not the instances) ? I'm not experience with json (which is why I don't know) but It appears to me that in order to work such a solution would have to do a backtracking search of potential matches with schema for each object in the array (much like in the language prolog for example) and this would be pretty slow - but I don't know the depth to which json validators are required to go.

Still playing with it trying to get a structure to work.

andy
2012/7/24 Andy:
>>>> json-schema+unsubscribe@googlegroups.com.
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/json-schema?hl=en.
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "JSON Schema" group.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msg/json-schema/-/c_lIcMHJEjkJ.
>>>
>>> To post to this group, send email to json-...@googlegroups.com.
>>> To unsubscribe from this group, send email to
>>> json-schema+unsubscribe@googlegroups.com.
>>> For more options, visit this group at
>>> http://groups.google.com/group/json-schema?hl=en.
>>
>>
> --
> You received this message because you are subscribed to the Google Groups
> "JSON Schema" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/json-schema/-/kOIY3PbnUhcJ.
>
> To post to this group, send email to json-...@googlegroups.com.
> To unsubscribe from this group, send email to
> json-schema+unsubscribe@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/json-schema?hl=en.
>>>> json-schema+unsubscribe@googlegroups.com.
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/json-schema?hl=en.
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "JSON Schema" group.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msg/json-schema/-/c_lIcMHJEjkJ.
>>>
>>> To post to this group, send email to json-...@googlegroups.com.
>>> To unsubscribe from this group, send email to
>>> json-schema+unsubscribe@googlegroups.com.
>>> For more options, visit this group at
>>> http://groups.google.com/group/json-schema?hl=en.
>>
>>
> --
> You received this message because you are subscribed to the Google Groups
> "JSON Schema" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/json-schema/-/kOIY3PbnUhcJ.
>
> To post to this group, send email to json-...@googlegroups.com.
> To unsubscribe from this group, send email to
> json-schema+unsubscribe@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/json-schema?hl=en.
>>>> json-schema+unsubscribe@googlegroups.com.
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/json-schema?hl=en.
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "JSON Schema" group.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msg/json-schema/-/c_lIcMHJEjkJ.
>>>
>>> To post to this group, send email to json-...@googlegroups.com.
>>> To unsubscribe from this group, send email to
>>> json-schema+unsubscribe@googlegroups.com.
>>> For more options, visit this group at
>>> http://groups.google.com/group/json-schema?hl=en.
>>
>>
> --
> You received this message because you are subscribed to the Google Groups
> "JSON Schema" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/json-schema/-/kOIY3PbnUhcJ.
>
> To post to this group, send email to json-...@googlegroups.com.
> To unsubscribe from this group, send email to
> json-schema+unsubscribe@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/json-schema?hl=en.
>>>> json-schema+unsubscribe@googlegroups.com.
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/json-schema?hl=en.
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "JSON Schema" group.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msg/json-schema/-/c_lIcMHJEjkJ.
>>>
>>> To post to this group, send email to json-...@googlegroups.com.
>>> To unsubscribe from this group, send email to
>>> json-schema+unsubscribe@googlegroups.com.
>>> For more options, visit this group at
>>> http://groups.google.com/group/json-schema?hl=en.
>>
>>
> --
> You received this message because you are subscribed to the Google Groups
> "JSON Schema" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/json-schema/-/kOIY3PbnUhcJ.
>
> To post to this group, send email to json-...@googlegroups.com.
> To unsubscribe from this group, send email to
> json-schema+unsubscribe@googlegroups.com.

David

unread,
Jul 25, 2012, 3:55:01 AM7/25/12
to json-...@googlegroups.com, aute...@uni-muenster.de
It sounds to me like you might be able to use complex types in combination with enums?

{
  "type": "array",
  "items": {
    "type": [
      {
        "type": "object",
        "properties": {
          "property": {"enum": ["colour"]},
          "value": {"type": "string", "format": "color"}
        }
      },
      {
        "type": "object",
        "properties": {
          "property": {"enum": ["screenwidth"]},
          "value": {"type": "integer", "minimum": 1}
        }
      }
    ]
  }
}

So the overall object is an array.  Each item in that array has to be one of the two types - one type only matches property="colour" and specifies value as a CSS colour, and the other type matches property="screenwidth" and specifies value as a positive integer.  The items can be in any order.

If the definitions have more in common (like the "condition" value you had originally) then you could, as suggested earlier, have them extend a common base schema, but that's just tidyiness.

Andy Heath

unread,
Jul 25, 2012, 4:36:07 AM7/25/12
to json-...@googlegroups.com, aute...@uni-muenster.de
Looks like a nice idea David. I made some tiny mods to fit my use-case better (but still the generic problem).
Are you able to cast your eye over this and tell me why it doesn't work (btw: not worried about strings/integers nor enum versus pattern, just trying to get a structure that works then I can expand it to incorporate the data I need (which has many properties and values and vocabs of half a dozen possible terms for each).

schema:


{
  "type": "array",
  "items": {
    "type": [
      {
        "type": "object",
        "properties": {
          "property": {"enum": ["colour"]},
          "value": {"type": "string", "pattern": "^red$|^blue$|^green$"}

        }
      },
      {
        "type": "object",
        "properties": {
          "property": {"enum": ["screenwidth"]},
          "value": {"type": "string", "pattern": "^1024$"}
        }
      }
    ]
  }
}


Instance that should be valid imho

[

    {

        "property": "colour",
        "value" : "red"

    },

    {
        "property" : "acreenwidth",
        "value" : "1024"

    }
]

but isn't valid using  http://jsonschemalint.com/

andy

Andy Heath

unread,
Jul 25, 2012, 4:37:59 AM7/25/12
to json-...@googlegroups.com, aute...@uni-muenster.de
btw: the solution must not require the records are ordered in the set.
andy

Andy Heath

unread,
Jul 25, 2012, 6:34:10 AM7/25/12
to json-...@googlegroups.com
ok, it works - with union of types.  Thankyou everyone, particularly David, who suggested the solution.

It doesn't work with http://jsonschemalint.com/ but it does work with JSV I fetched from github myself (which may be a later version).

Thanks everyone.

andy

Chris Miles

unread,
Jul 25, 2012, 7:30:52 AM7/25/12
to json-...@googlegroups.com
Just for info:

Works with http://jsonschemalint.com/ provided you fix the data - "screenwidth" instead of "acreenwidth"

Chris
--
You received this message because you are subscribed to the Google Groups "JSON Schema" group.
To view this discussion on the web visit https://groups.google.com/d/msg/json-schema/-/C96uXsoK9HcJ.

To post to this group, send email to json-...@googlegroups.com.
To unsubscribe from this group, send email to json-schema...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages