Re: Dependencies between two "enums"

3,278 views
Skip to first unread message

Geraint (David)

unread,
Jan 25, 2013, 4:10:59 AM1/25/13
to json-...@googlegroups.com, kude...@alphanull.de
OK - so basically, you want to say "if main is X1, then the everything else must by Y1.  If the main is X2, then everything else is X2".

The simplest way to do this in v4 is "oneOf".  You would simply present an option for each of your combinations (main is value1, value2, ... or not defined).

{
    "type": "object",
    "oneOf": [
        {
            "required": ["main"],
            "properties": {
                "main": {"enum": ["value1"]},

                "subCategory": {...},
                ... // all your constraints for main=value1
            },
        },
        {
            "required": ["main"],
            "properties": {
                "main": {"enum": ["value2"]},

                "subCategory": {...},
                ... // all your constraints for main=value2
            }
        },

        ... // all your other options

        {
            "not": {                         // matches only if main is not defined
                "required": ["main"]
            }
            "properties": {
                "subCategory": {
                    "enum": [null]
                }
            }
        }
    ]
}

In version 3, it is similar.  You put the big array in "type", not "oneOf", and you'll have to use "disallow" instead of "not".

On Saturday, January 19, 2013 4:12:09 PM UTC, kude...@alphanull.de wrote:
Hello!

First of all, I know that some similar questions were already asked, but I am still struggling, so I hope you can enlighten me a bit:

In my project, I need to ask the user about two categories, let's call them "main" and "sub". The "main" category is just an enum with a predefined set of values. Since I also want to include a title in the schema, I ended up with something like this:

"main" : {
  "type" :[ 
     {"enum" : ["main1"], title :"main1 title"},
     {"enum" : ["main2"], title :"main2 title"},
     {"enum" : ["main3"], title :"main3 title"}
  ]
}

Now, if the user selects a main category, he can also enter a sub category, but this depends on the main category!

Based on the selection in "main", I want to

a) Present (and validate) a certain matching sub category - OR -
b) Prevent the user from entering ANY sub category, if ONLY a main category exists (not all main categories actually have defined sub categories) - OR -
c) Prevent the user from entering ANY sub category, if a main category hasn't been selected yet

Now, as I watched the former diskussions I understand that v4 of the draft would solve this quite differently to v3. Since I am not sure what validator I will use later, and since not all validators support v4 yet, how would I do this:

* in v3?
* in v4?

Or would you actually recomment to go straight to v4 nonetheless?

Any help is greatly appreciated, thank you in advance!

frontend_dev

unread,
Jan 30, 2013, 10:27:11 AM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de
Unfortunately, I am still stuck. I also tried something like this:

{
   
    "type": "object",
   
    "definitions" : {
       
        "main_food" : { "properties" : { "main" : { "enum" : ["food"] }}},
        "main_drinks" : { "properties" : { "main" : { "enum" : ["drinks"] }}}
       
    },
   
    "properties" : {
       
        "main" : { "enum" : ["drinks","food"] },
       
        "sub" : {
       
            "type" : "string",
            "oneOf": [
               
                {
                    "$ref" : "#/definitions/main_food",   
                    "enum": ["bread", "steak"]
                },
           
                {
                    "$ref" : "#/definitions/main_drinks",   
                    "enum": ["water", "juice"]
                }
           
            ]           
        }
       
    }
   
}


But then I get an "instance does not match exactly one schema" error.

So, is there any other way to reference "main" from within "sub"?

Francis Galiegue

unread,
Jan 30, 2013, 10:31:54 AM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de
Grrr, I really need to fix that reporting. In progress...

> So, is there any other way to reference "main" from within "sub"?
>

The problem here is with your schema. First you tell it to reference
to one definition _but then_ you constrain it with an enum:

> {
> "$ref" : "#/definitions/main_drinks",
> "enum": ["water", "juice"]
> }

Beware: enums apply to _the whole instance_. Which means an instance
won't validate successfully until it has the _exact representation_ of
the values in the enum (that is, JSON Strings "water" or "juice"!

I believe you wanted to enclose that enum into a "property".

--
Francis Galiegue, fgal...@gmail.com
Try out your JSON Schemas: http://json-schema-validator.herokuapp.com

frontend_dev

unread,
Jan 30, 2013, 11:38:38 AM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de
The problem here is with your schema. First you tell it to reference
to one definition _but then_ you constrain it with an enum:

Well, I know that my attempt does not work, but I simply don't know how to do it, if it is even possible.

Of course, a working example would look like this:

{
    "type": "object",
    "oneOf": [
        {

            "properties": {
                "main": {"enum": ["food"]},
                "sub": {"enum": ["break","steak"]}
            },

        },
        {
            "properties": {
                "main": {"enum": ["drinks"]},
                "sub": {"enum": ["water","juice"]}
            }
        }
    ]
}

But since I also want to render the data based on that schema in a form, it would be very hard to find out what properties actually exist, what type they are and and which values they can have.

I actually tried that schema in a tool that does something similar - "jsonary" - and this tool also is not able to display the "main" property as an enum (ie a <select> box).
 
So something like this would be easier to parse:


{
   
    "type": "object",

    "properties" : {
        "main" : { "enum" : ["drinks","food"] },
        "sub" : {
            "type" : "string",
            "oneOf": [
                {
                    // IF MAIN === "food"    
                    "enum": ["bread", "steak"]
                },
                {
                    // IF MAIN === "drinks  
                    "enum": ["water", "juice"]
                }    
            ]           
        }
    }
}


With this structure I still can find out easily which properties my object actally has, and how to render each field. All I have to do in addition is to find out which of the "oneOf" Schemas are actually valid and choose the values of the "sub" field accordingly.

The problem I have is how to write the "bold red" part in a JSON (v04) schema?

Francis Galiegue

unread,
Jan 30, 2013, 12:02:48 PM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de
On Wed, Jan 30, 2013 at 5:38 PM, frontend_dev <kude...@alphanull.de> wrote:
[...]
>
> With this structure I still can find out easily which properties my object
> actally has, and how to render each field. All I have to do in addition is
> to find out which of the "oneOf" Schemas are actually valid and choose the
> values of the "sub" field accordingly.
>
> The problem I have is how to write the "bold red" part in a JSON (v04)
> schema?
>

OK, so your problem is not really with validation or schema writing
per se, but with form rendering?

That is a territory which JSON Schema doesn't venture into, since it
is quite application specific... In fact, it has no keyword to dictate
what a form would look like. It does have keywords to document fields,
though.

Whether that role belongs to JSON Schema is an interesting question.

Geraint (David)

unread,
Jan 30, 2013, 12:17:24 PM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de
Hi - developer of Jsonary here.

That's a bug I know about, but I've been short on time recently.  Fortunately, I've got some coding time reserved this evening for that exact issue, so I'll post here in a couple of hours when that's done.

I'm sorry for the wait...

Geraint

frontend_dev

unread,
Jan 30, 2013, 12:22:32 PM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de
OK, so your problem is not really with validation or schema writing
per se, but with form rendering?

Yes and no. The problem is how to write a schema, so that it also can be used for rendering. The "standard solution" makes this difficult imho.
 
That is a territory which JSON Schema doesn't venture into, since it
is quite application specific... In fact, it has no keyword to dictate
what a form would look like. It does have keywords to document fields,
though.

Yes, but the information from the schema is also very very useful for rendering. An example:

* property is "enum" -> Render a selectbox.
* property is "Boolean" -> Render a checkbox

* property is required -> Display a red asterik char
* property is read only -> Disable <input> field, or just display as string

and so on ....

This should also work with JSON Schema, and in fact there is a tool - jsonary - which attempts to do exactly that.

Imho it is very tempting and almost logical to use the schema also for rendering, since the schema also contains information which is important for presentation, like "required" and so on.

Of course my problem remains: Is it actually possible to have a structure like described above, so it can be parsed by a renderer more easily?

frontend_dev

unread,
Jan 30, 2013, 12:26:06 PM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de
Hi Geraint,

nice to hear from you, interesting tool you have ;)

so, given the schema:


{
    "type": "object",
    "oneOf": [
        {
            "properties": {
                "main": {"enum": ["food"]},
                "sub": {"enum": ["break","steak"]}
            },
        },
        {
            "properties": {
                "main": {"enum": ["drinks"]},
                "sub": {"enum": ["water","juice"]}
            }
        }
    ]
}


How do you actually figure out that "main" is really an enum and can have the values "drinks" and "food" then?

Especially when the schema gets more complex, I think this wouldn't be an easy task.

If you have an idea to solve this problem without rather complex code, I would be VERY happy to hear about ;)

Geraint (David)

unread,
Jan 30, 2013, 12:52:10 PM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de
With that structure, it's difficult to write code that realises "main" should be a dropdown.  In fact - how should I, as a human, know that is the case?  An equally valid interpretation would be to have "sub" as the 'master' dropdown, and the value of "main" entirely dependent on the selection in 'sub'.  The way you have defined it there, it is completely symmetrical - neither "main" nor "sub" has priority.

What I intend to code tonight is instead a "switcher" renderer that will allow you to select which of the schemas from "oneOf" you want to be using.  So instead of using the drop-down for main, you could give each option in "oneOf" a title (e.g. "Food Menu", "Drinks Menu") and then be able to switch between the two.

Would that work for you?

frontend_dev

unread,
Jan 30, 2013, 1:27:18 PM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de
With that structure, it's difficult to write code that realises "main" should be a dropdown.

Right, this is exactly my problem.
 
  In fact - how should I, as a human, know that is the case?  An equally valid interpretation would be to have "sub" as the 'master' dropdown, and the value of "main" entirely dependent on the selection in 'sub'.  The way you have defined it there, it is completely symmetrical - neither "main" nor "sub" has priority.

I think with the structure I have in my 4th post this would be possible. Here, it is quite clear what "main" is and what values it can have, so easy to render this.

As for the sub value, the renderer first encounters the "anyOf" Tag. All it has to then is to decide which one of the subschemas is valid, and then read the correct values for "sub".

Of course, there is still the question if I can do that at all without breaking the whole structure apart.

the actual problem seems to be that there is no way to referenence a "sibling" (or parent) in relation to the property I am validating. So something like this would also help:

{
   
    "type": "object",
   
    "properties" : {
       
        "main" : { "enum" : ["drinks","food"] },
       
        "sub" : {
       
            "type" : "string",
            "oneOf": [
               
                {
                    "allOf" : [
                        { "#/properties/main" : { "enum" : ["drinks"] } },   
                        { "enum": ["juice", "water"] }
                    ]
                },
           
                {
                    "allOf" : [
                        { "#/properties/main" : { "enum" : ["food"] } },   
                        { "enum": ["bread", "steak"] }
                    ]
                }
           
            ]           
        }
       
    }
   
}


I know that the example does not work, just to make the problem more clear. The question is simply: how do I make a reference to the "main" property inside of "sub"?
 
What I intend to code tonight is instead a "switcher" renderer that will allow you to select which of the schemas from "oneOf" you want to be using.  So instead of using the drop-down for main, you could give each option in "oneOf" a title (e.g. "Food Menu", "Drinks Menu") and then be able to switch between the two.

Well, I'd like to see your solution, but how do you implement this "switch"? I also have thought of just extending the schema, but then it will not validate, or to be more precise: it will validate OK with more cases than it should, even cases where main=drinks and sub=steak, which shouldn't be valid of course.

Needing a second object which defines this "switch" would also be not too optimal imho.
 

Geraint (David)

unread,
Jan 30, 2013, 1:52:13 PM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de

Roughly: Jsonary knows which schemas are "fixed" (explicitly set, or inherited from the parent), and which ones are not.

Hopefully, the code should be fairly readable when I'm done. :)

Geraint (David)

unread,
Jan 30, 2013, 1:54:30 PM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de


On Wednesday, January 30, 2013 6:27:18 PM UTC, frontend_dev wrote:
With that structure, it's difficult to write code that realises "main" should be a dropdown.

Right, this is exactly my problem.
 
  In fact - how should I, as a human, know that is the case?  An equally valid interpretation would be to have "sub" as the 'master' dropdown, and the value of "main" entirely dependent on the selection in 'sub'.  The way you have defined it there, it is completely symmetrical - neither "main" nor "sub" has priority.

I think with the structure I have in my 4th post this would be possible. Here, it is quite clear what "main" is and what values it can have, so easy to render this.

As for the sub value, the renderer first encounters the "anyOf" Tag. All it has to then is to decide which one of the subschemas is valid, and then read the correct values for "sub".

Of course, there is still the question if I can do that at all without breaking the whole structure apart.

the actual problem seems to be that there is no way to referenence a "sibling" (or parent) in relation to the property I am validating. So something like this would also help:

{
   
    "type": "object",
   
    "properties" : {
       
        "main" : { "enum" : ["drinks","food"] },
       
        "sub" : {
       
            "type" : "string",
            "oneOf": [
               
                {
                    "allOf" : [
                        { "#/properties/main" : { "enum" : ["drinks"] } },   
                        { "enum": ["juice", "water"] }
                    ]
                },
           
                {
                    "allOf" : [
                        { "#/properties/main" : { "enum" : ["food"] } },   
                        { "enum": ["bread", "steak"] }
                    ]
                }
           
            ]           
        }
       
    }
   
}


I know that the example does not work, just to make the problem more clear. The question is simply: how do I make a reference to the "main" property inside of "sub"?

You can't.  Validation of a given piece of data against a given schema can not depend on the data's parent or siblings - only on its children.

The only way to do this is to provide multiple options (using oneOf/anyOf) in the parent schema.

frontend_dev

unread,
Jan 30, 2013, 2:10:10 PM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de
You can't.  Validation of a given piece of data against a given schema can not depend on the data's parent or siblings - only on its children.

I fear you are right - in this case I can try as hard as I want ....

OK, so would it make sense to extend the JSON Schema with an attribute like "scope" so that these kind of referencing would be actually possible?  All I would have to do then is to tell the validator the "starting scope" from which it then can access the desired properties, even if they are parents or siblings.

Or am I missing something here?

Sorry if my questions may sound stupid, but I am actually very new to JSON Schema, and I really like to use it not only for validation.

frontend_dev

unread,
Jan 30, 2013, 2:16:13 PM1/30/13
to json-...@googlegroups.com, kude...@alphanull.de
maybe something like this:

{
   
    "type": "object",
   
    "properties" : {
       
        "main" : { "enum" : ["drinks","food"] },
       
        "sub" : {
       
            "type" : "string",
            "oneOf": [
               
                {
                    "allOf" : [
                        { "scope" : "#/properties/main", "enum" : ["drinks"] },   
                        { "enum": ["juice", "water"] }
                    ]
                },
           
                {
                    "allOf" : [
                        { "scope" : "#/properties/main", "enum" : ["food"] },   
                        { "enum": ["bread", "steak"] }
                    ]
                }
           
            ]           
        }
       
    }
   
}


this way I could tell the validator that I explicitly refer to the "main" property, and not an additional property of "sub".

Geraint Luff

unread,
Jan 30, 2013, 6:16:15 PM1/30/13
to json-...@googlegroups.com
I think the issue here is that with the current spec, you can fully describe what data is or isn't allowed, using anyOf/oneOf/not in the top-level schema.  You don't need your "scope" attribute to describe the possible structure of the data.

What you're trying to do is to rig the generated UI to behave a certain way.  I think that's more of a "stylesheet" kind of issue (something I've also been thinking about a lot recently) than a "schema" one.

OK - as promised, I have updated Jsonary.  What I've put in isn't perfect, but the basic principle is sound.  Try going to this page and entering the data and schema from this Gist, which is based on your example.  In editable mode, it should show a little button labelled "S" that allows you to switch between the options in "oneOf".

I think that this interface accurately represents the constraints as they are defined in the schema - please let me know whether it's useful (or even functional!) for you or not.


--
You received this message because you are subscribed to the Google Groups "JSON Schema" group.
To unsubscribe from this group and stop receiving emails from it, send an email to json-schema...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

frontend_dev

unread,
Jan 31, 2013, 12:06:52 PM1/31/13
to json-...@googlegroups.com
I think the issue here is that with the current spec, you can fully describe what data is or isn't allowed, using anyOf/oneOf/not in the top-level schema.  You don't need your "scope" attribute to describe the possible structure of the data.

Well, I dont "need" something like a scope to specify such a dependency, but imho the ability to branch were the branching actually takes place, without tearing the whole structure apart, that would make life so much easier, and not only for auto-generating UIs. Also think of readability, with the only one solution that works right now, I assume you will quickly lose overview if things get more complex. Think of editing this schema in a GUI for example.

While I really like the "oneOf/anyOf etc" solution, it has one major drawback imho, and that is the inability to reference parent or sibling objects. With this restriction, I am simply forced to "branch" my Schema always at the "root level", even if the actual dependency is in a deeper level.

Therefore it isn't only harder to "get" the overall structure, it is also much harder to see where the actual dependencies / branches are.

In addition, it does not feel very DRY, as I have to replicate the whole structure, beginning from "root"  in each of the different subschemas. Think of more complex cases, or - as in my case - if you have about 10 main categories, with each having 10 additional subcategories. Think this will lead to very convoluted schemas.


What you're trying to do is to rig the generated UI to behave a certain way.  I think that's more of a "stylesheet" kind of issue (something I've also been thinking about a lot recently) than a "schema" one.

I also have thought quite a lot about that, and I strongly have to disagree ;) Why adding a second structure when almost all I need to present the data is already in the schema? If I would write such a "presentation format" from scratch, it would look more or less identical to a JSON scheme! Why duplicating things then?

Because one important outcome of my thoughts was the insight that I absolutely do not want to specify fixed presentations in the renderer config. The beautiful thing about such a scheme is that it already contains the needed information, but in a more abstract way, and it is still up to the renderer how to present such information. Think of different GUIs using the same data description.

So for example I don't want to hardcode that a certain field should always be presented as an <input> field. Why should I? In this case, the renderer would better look at the "maxLength" property to make such a decision. Maybe in one UI I have more room for a wide <input> field, maybe in another UI (mobile!) it would make more sense to render a <textarea> instead or use a completely different representation than the desktop client. No need to specify the concrete representation, let the client decide what's best.

So, in short, I feel that using a CSS like presentation format is not the right way here - at least for me.
 
OK - as promised, I have updated Jsonary.  What I've put in isn't perfect, but the basic principle is sound.  Try going to this page and entering the data and schema from this Gist, which is based on your example.  In editable mode, it should show a little button labelled "S" that allows you to switch between the options in "oneOf".

Hmm, does not work. Now, neither of the 2 fields is rendered as a dropdown (with the former version, at least the "sub" field was)

And I am still convinced that a mechanism like I proposed would also help jsonary a lot.

Also I think the usefulness of a JSON Schema also for representation is also severly underestimated - basically everything we need is there even right now. Just think of taking a schema, the data and feeding that to a renderer which outputs a nice HTML5 Form, even complete with validation. Since I have LOTS of basically similar forms to make (who doesn't? ;) it would be a HUGE timesaver to have such a thing.

And I still think my proposal would make "anyOf" so much more powerful and better to maintain also for other use cases. Basically, the only thing that is missing (imho) is a "counterpart" to "$ref", the ability to use a JSON pointer not only for content, but also for the keys / properties. I also think that this shouldn't be tooo hard to implement, or am I wrong here?

Just use a "scope" keyword, or simply something like this: "#/path/to/property" : { .... }

That's all!

This could also be useful for other things except "oneof". What do you think? Any realistic chance of seing something like this implemented?

Francis Galiegue

unread,
Jan 31, 2013, 12:30:04 PM1/31/13
to json-...@googlegroups.com
On Thu, Jan 31, 2013 at 6:06 PM, frontend_dev <kude...@alphanull.de> wrote:
[...]
>
> Well, I dont "need" something like a scope to specify such a dependency, but
> imho the ability to branch were the branching actually takes place, without
> tearing the whole structure apart, that would make life so much easier, and
> not only for auto-generating UIs. Also think of readability, with the only
> one solution that works right now, I assume you will quickly lose overview
> if things get more complex. Think of editing this schema in a GUI for
> example.
>

There is one thing I don't get. The end user will never see the schema
anyway, only the form itself. And JSON Schema already offers all
facilities for refering to other schemas.

So, what is the problem, really? Just carry over the context with you
when you generate the form, job done. You don't even need to carry
over all validation information since you can let that to a validator.

Francis Galiegue

unread,
Jan 31, 2013, 12:35:56 PM1/31/13
to json-...@googlegroups.com
On Thu, Jan 31, 2013 at 6:30 PM, Francis Galiegue <fgal...@gmail.com> wrote:
[...]
>
> There is one thing I don't get. The end user will never see the schema
> anyway, only the form itself. And JSON Schema already offers all
> facilities for refering to other schemas.
>
> So, what is the problem, really? Just carry over the context with you
> when you generate the form, job done. You don't even need to carry
> over all validation information since you can let that to a validator.
>

And there is something else as well: say you have a schema for a
brewery. You want to buy some beer. So far so good.

Now, vendor A wants people to select the country of production. And
vendor B wants people to select the type (ale, trappist) first.

If your schema were written so as to _force_ GUIs one way or another, you lose.

frontend_dev

unread,
Jan 31, 2013, 12:58:25 PM1/31/13
to json-...@googlegroups.com

There is one thing I don't get. The end user will never see the schema
anyway, only the form itself.

That's right, but still the UI must decide how to render a given field. And that could also be accomplished with a schema.
 

And JSON Schema already offers all
facilities for refering to other schemas.

But not for refering to other properties as it seems - thats the one missing thing I see.


So, what is the problem, really? Just carry over the context with you
when you generate the form, job done. You don't even need to carry
over all validation information since you can let that to a validator.

the problems remains as described above:

{
    "type": "object",
    "oneOf": [
        {
            "properties": {
                "main": {"enum": ["food"]},
                "sub": {"enum": ["break","steak"]}
            },
        },
        {
            "properties": {
                "main": {"enum": ["drinks"]},
                "sub": {"enum": ["water","juice"]}
            }
        }
    ]
}

How do you actually figure out then what type "main" is and what values it can have? What properties does the object actually have? Not too easy I think, esp with more complicated examples.


Now, compare this to:

{
    "type": "object",
    "properties" : {
        "main" : { "enum" : ["drinks","food"] },
        "sub" : {
            "oneOf": [
                {
                    "#/properties/main" : { "enum" : ["drinks"]},   
                    "enum": ["juice", "water"]
                },
                {
                    "#/properties/main" : { "enum" : ["food"]},   
                    "enum": ["bread", "steak"]
                }
            ]           
        }
    }
}


In this case, I see the following advantages:
  • overall structure still intact, easy to see what properties my object has
  • very clear now what "main" actually is and what values it can have
  • also we can see that it is actually the property "sub" which has a "branch", ie this is the one which can have several values, no need for complicated parsing
  • more explicit expression of the actual dependency, formulated within "sub", right where it applies to.

Hope this makes it more clear. Sorry if my English is far from perfect - I am not a native speaker, so I hope you get my point.

frontend_dev

unread,
Jan 31, 2013, 1:02:38 PM1/31/13
to json-...@googlegroups.com

If your schema were written so as to _force_ GUIs one way or another, you lose.

Well, that is exactly the point I try to avoid! So, use a rather formal and abstract definition of your data (like a JSON Schema!) and let the client decide what to do.

In order to achieve this, I should be able to know without too much hassle what properties an object has, what type of data there is and what constraints etc there are. And this is exactly the problem with "anyOf" branches starting right from "root".

Geraint Luff

unread,
Jan 31, 2013, 10:38:32 PM1/31/13
to json-...@googlegroups.com
On 31 January 2013 17:06, frontend_dev <kude...@alphanull.de> wrote:
I think the issue here is that with the current spec, you can fully describe what data is or isn't allowed, using anyOf/oneOf/not in the top-level schema.  You don't need your "scope" attribute to describe the possible structure of the data.

Well, I dont "need" something like a scope to specify such a dependency, but imho the ability to branch were the branching actually takes place, without tearing the whole structure apart, that would make life so much easier, and not only for auto-generating UIs. Also think of readability, with the only one solution that works right now, I assume you will quickly lose overview if things get more complex. Think of editing this schema in a GUI for example.

While I really like the "oneOf/anyOf etc" solution, it has one major drawback imho, and that is the inability to reference parent or sibling objects. With this restriction, I am simply forced to "branch" my Schema always at the "root level", even if the actual dependency is in a deeper level.

But you can still specify what you want.
 
Therefore it isn't only harder to "get" the overall structure, it is also much harder to see where the actual dependencies / branches are.

In addition, it does not feel very DRY, as I have to replicate the whole structure, beginning from "root"  in each of the different subschemas. Think of more complex cases, or - as in my case - if you have about 10 main categories, with each having 10 additional subcategories. Think this will lead to very convoluted schemas.

I don't see the problem here, I think.  You have 10 options in "oneOf" at the top level.  How is this greatly more complicated than having 10 separate "if/then"-style structures?
 
What you're trying to do is to rig the generated UI to behave a certain way.  I think that's more of a "stylesheet" kind of issue (something I've also been thinking about a lot recently) than a "schema" one.

I also have thought quite a lot about that, and I strongly have to disagree ;) Why adding a second structure when almost all I need to present the data is already in the schema? If I would write such a "presentation format" from scratch, it would look more or less identical to a JSON scheme! Why duplicating things then?

Because one important outcome of my thoughts was the insight that I absolutely do not want to specify fixed presentations in the renderer config. The beautiful thing about such a scheme is that it already contains the needed information, but in a more abstract way, and it is still up to the renderer how to present such information. Think of different GUIs using the same data description.

The schema I liked (this Gist) can specify the "data description" you want.

But as I said earlier - there is nothing in that "data description" that says the UI should present "main" as the primary dropdown.  In fact, it would be simpler to present a dropdown for "sub" with the possible values "bread"/"steak"/"water"/"juice", and then simply use the value from that to determine what "main"'s value should be.

However, you seemed to definitely want things the other way around - "main" dropdown containing all possible options, with "sub" dropdown being filtered depending on the value of "main".  That is not a data constraint - that is a presentation constraint.

So for example I don't want to hardcode that a certain field should always be presented as an <input> field. Why should I? In this case, the renderer would better look at the "maxLength" property to make such a decision. Maybe in one UI I have more room for a wide <input> field, maybe in another UI (mobile!) it would make more sense to render a <textarea> instead or use a completely different representation than the desktop client. No need to specify the concrete representation, let the client decide what's best.

I totally agree.  In fact, the modular renderer system in Jsonary is tailored towards this.

But would you not consider it to be rendering "incorrectly" if one renderer always presented "sub" with all four options, and used them to select main?  It's back to front, but it's a valid editing interface for the data.

My objection was mainly to the idea that "main" is given priority here.

So, in short, I feel that using a CSS like presentation format is not the right way here - at least for me.
 
OK - as promised, I have updated Jsonary.  What I've put in isn't perfect, but the basic principle is sound.  Try going to this page and entering the data and schema from this Gist, which is based on your example.  In editable mode, it should show a little button labelled "S" that allows you to switch between the options in "oneOf".

Hmm, does not work. Now, neither of the 2 fields is rendered as a dropdown (with the former version, at least the "sub" field was)

Did you check the "editable" checkbox?  Otherwise it simply annotates the data with schema titles.

If so: what browser are you using?  Do you see any errors?
 
And I am still convinced that a mechanism like I proposed would also help jsonary a lot.

Also I think the usefulness of a JSON Schema also for representation is also severly underestimated - basically everything we need is there even right now. Just think of taking a schema, the data and feeding that to a renderer which outputs a nice HTML5 Form, even complete with validation. Since I have LOTS of basically similar forms to make (who doesn't? ;) it would be a HUGE timesaver to have such a thing.

Not by me!  I am most definitely not underestimating the possibilities of this.  Just wait until I code Node.js support for Jsonary... :D  It's gonna *rock*.

The thing is - everything we need to describe the data is there now (as shown by the example schemas).  So I'm wary about adding a proposal that doesn't allow you to express anything new, just express it differently, so that form renderers can pick it up.  Does that make sense?
 
And I still think my proposal would make "anyOf" so much more powerful and better to maintain also for other use cases. Basically, the only thing that is missing (imho) is a "counterpart" to "$ref", the ability to use a JSON pointer not only for content, but also for the keys / properties. I also think that this shouldn't be tooo hard to implement, or am I wrong here?

Just use a "scope" keyword, or simply something like this: "#/path/to/property" : { .... }

Hmm... if that path refers to a position within the data, it would need to somehow be a relative path within a document, not absolute.  Otherwise, what if somebody writes a data format that includes your one embedded inside it?

If that path refers to a schema, that's more interesting.  It's selective schema enhancement.  I can see how that would be useful in assembling UIs.

What are the other non-UI benefits of it, though?  What can you say with it that you can't already say?
 
That's all!

This could also be useful for other things except "oneof". What do you think? Any realistic chance of seing something like this implemented?

It's an interesting idea, certainly.

My main reservation is that complex schema enhancement like that would make a lot of things (even simple validation) more complicated, and I haven't yet seen a situation where it would be useful except for rigging an auto-generated UI to behave a particular way.

It's worth thinking about, though.  We currently have a "Wild Ideas Wishlist" on the wiki on GitHub that holds a bunch of blue-sky feature suggestions.  I think I'll add this one to the list. :)

Geraint Luff

unread,
Jan 31, 2013, 10:42:25 PM1/31/13
to json-...@googlegroups.com
On 31 January 2013 17:35, Francis Galiegue <fgal...@gmail.com> wrote:
On Thu, Jan 31, 2013 at 6:30 PM, Francis Galiegue <fgal...@gmail.com> wrote:
[...]
>
> There is one thing I don't get. The end user will never see the schema
> anyway, only the form itself. And JSON Schema already offers all
> facilities for refering to other schemas.
>
> So, what is the problem, really? Just carry over the context with you
> when you generate the form, job done. You don't even need to carry
> over all validation information since you can let that to a validator.
>

And there is something else as well: say you have a schema for a
brewery. You want to buy some beer. So far so good.

Now, vendor A wants people to select the country of production. And
vendor B wants people to select the type (ale, trappist) first.

Good example - very similar to the case we have here (where it would be theoretically possible to choose "sub" first and then "main"), but there is not a "correct" way around.

You also remind me that it's been a while since I last went to Belgium... :p
 
If your schema were written so as to _force_ GUIs one way or another, you lose.

--
Francis Galiegue, fgal...@gmail.com
Try out your JSON Schemas: http://json-schema-validator.herokuapp.com

Geraint Luff

unread,
Jan 31, 2013, 10:52:46 PM1/31/13
to json-...@googlegroups.com
On 31 January 2013 17:58, frontend_dev <kude...@alphanull.de> wrote:

There is one thing I don't get. The end user will never see the schema
anyway, only the form itself.

That's right, but still the UI must decide how to render a given field. And that could also be accomplished with a schema.
 

And JSON Schema already offers all
facilities for refering to other schemas.

But not for refering to other properties as it seems - thats the one missing thing I see.


So, what is the problem, really? Just carry over the context with you
when you generate the form, job done. You don't even need to carry
over all validation information since you can let that to a validator.

the problems remains as described above:

{
    "type": "object",
    "oneOf": [
        {
            "properties": {
                "main": {"enum": ["food"]},
                "sub": {"enum": ["break","steak"]}
            },
        },
        {
            "properties": {
                "main": {"enum": ["drinks"]},
                "sub": {"enum": ["water","juice"]}
            }
        }
    ]
}

How do you actually figure out then what type "main" is and what values it can have? What properties does the object actually have? Not too easy I think, esp with more complicated examples.

Well, not that difficult - you could simply enumerate all the possible anyOf/oneOf combinations, and provide the union of the allowed enum values for each one.

The question is how to determine that "main" is the correct field to be doing this on, but not "sub".  I mean, if you did the same calculation on "sub", then it would always show all four options.

Now, compare this to:

{
    "type": "object",
    "properties" : {
        "main" : { "enum" : ["drinks","food"] },
        "sub" : {
            "oneOf": [
                {
                    "#/properties/main" : { "enum" : ["drinks"]},   
                    "enum": ["juice", "water"]
                },
                {
                    "#/properties/main" : { "enum" : ["food"]},   
                    "enum": ["bread", "steak"]
                }
            ]           
        }
    }
}


In this case, I see the following advantages:
  • overall structure still intact, easy to see what properties my object has
  • very clear now what "main" actually is and what values it can have
  • also we can see that it is actually the property "sub" which has a "branch", ie this is the one which can have several values, no need for complicated parsing
  • more explicit expression of the actual dependency, formulated within "sub", right where it applies to.

Hope this makes it more clear. Sorry if my English is far from perfect - I am not a native speaker, so I hope you get my point.

Ah, OK - so what you're proposing isn't intended to allow you to specify anything new.  However, it expresses it in a way that clearly gives priority to "main", and makes "sub" clearly dependent on that.

That's... actually a pretty good way of expressing it.
 
Francis's beer example is still relevant, though.  If you wrote the schema in this form, making beer type dependent on country of origin, then you make it extremely difficult to assemble a UI that allows you to specify beer type first.  This means that the schema is forcing UI decisions.

Whereas if you used "oneOf" or other structures at the root level instead, then it doesn't prejudice towards country-first or type-first.

frontend_dev

unread,
Feb 1, 2013, 8:24:52 AM2/1/13
to json-...@googlegroups.com
First of all, thanks a lot for your feedback. Let me add some comments:


While I really like the "oneOf/anyOf etc" solution, it has one major drawback imho, and that is the inability to reference parent or sibling objects. With this restriction, I am simply forced to "branch" my Schema always at the "root level", even if the actual dependency is in a deeper level.

But you can still specify what you want.

Yes, but in a (imho!) less structured and clear way.
 

I don't see the problem here, I think.  You have 10 options in "oneOf" at the top level.  How is this greatly more complicated than having 10 separate "if/then"-style structures?

Well, harder to read at least? Plus, we also want to generate the schema from the DB, so it should also be easier to construct with my alternate solution.
 

But as I said earlier - there is nothing in that "data description" that says the UI should present "main" as the primary dropdown.

Well, this might be another advantage of my proposal - there it should be quite clear what is the "primary" property.

 
 In fact, it would be simpler to present a dropdown for "sub" with the possible values "bread"/"steak"/"water"/"juice", and then simply use the value from that to determine what "main"'s value should be.

But that shouldn#
 

However, you seemed to definitely want things the other way around - "main" dropdown containing all possible options, with "sub" dropdown being filtered depending on the value of "main".  That is not a data constraint - that is a presentation constraint.

Well that is also a data constraint, isn't it?
 
In my example this is exactly what I want, because you _must_ select the main category first, or else it doesn't make sense.

The sub category selection changes _only_ if you change the main category.

Also keep in mind that there also will be default values if there wasn't a selection before - and in this special case, the UI actually has to care about correctly updating the "sub" dropdown - bit still using data from the scheme.

Even if there _shouldn't_ be any user validation errors from using this selections then, I can still use validation here to catch any programming errors.

Of course, there are many other properties in this object, and of course I want to use the schema for BOTH validation and presentation.

I totally agree.  In fact, the modular renderer system in Jsonary is tailored towards this.

Yes, I think we have similar goals ;)
 
But would you not consider it to be rendering "incorrectly" if one renderer always presented "sub" with all four options, and used them to select main?  It's back to front, but it's a valid editing interface for the data.

Yes, that would be incorrect, but I think I can avoid excatly this using my proposal.
 
Did you check the "editable" checkbox?  Otherwise it simply annotates the data with schema titles.

Ah well, yes I forgot to check that. But still, only "sub" is recognized as a dropdown.
 

Hmm... if that path refers to a position within the data, it would need to somehow be a relative path within a document, not absolute.  Otherwise, what if somebody writes a data format that includes your one embedded inside it?

Just use a JSON pointer, like with "$ref"? Of course, supporting both absolute and relative adressing would be cool.
 

What are the other non-UI benefits of it, though?  What can you say with it that you can't already say?

Like stated above: Readabiltiy, more clear expression of dependencies, overall structure still intact

And I am sure there could be more use cases where that mechanism would help, but I don't know right now what that could be ;)
 

It's worth thinking about, though.  We currently have a "Wild Ideas Wishlist" on the wiki on GitHub that holds a bunch of blue-sky feature suggestions.  I think I'll add this one to the list. :)

That would be greatly appreciated! If I can help any further please let me know.

frontend_dev

unread,
Feb 1, 2013, 8:36:57 AM2/1/13
to json-...@googlegroups.com

Now, vendor A wants people to select the country of production. And
vendor B wants people to select the type (ale, trappist) first.

Good example - very similar to the case we have here (where it would be theoretically possible to choose "sub" first and then "main"), but there is not a "correct" way around.

But that example is also a bit hypothetical, because that shouldn't be allowed in my case. So, "sub" is always dependent on "main", it simply can not be the other way.

Francis Galiegue

unread,
Feb 1, 2013, 8:54:37 AM2/1/13
to json-...@googlegroups.com
On Fri, Feb 1, 2013 at 2:36 PM, frontend_dev <kude...@alphanull.de> wrote:
[...]
>>
>> Good example - very similar to the case we have here (where it would be
>> theoretically possible to choose "sub" first and then "main"), but there is
>> not a "correct" way around.
>
>
> But that example is also a bit hypothetical, because that shouldn't be
> allowed in my case. So, "sub" is always dependent on "main", it simply can
> not be the other way.
>


Sorry, I have a different view on this. It is far from being
hypothetical. If you have a schema that you _share_ with others, you
shouldn't force feed the way people use the schema.

What is really needed here is a DSL for forms based on JSON Schema. A
json-forms spec?

frontend_dev

unread,
Feb 1, 2013, 8:55:17 AM2/1/13
to json-...@googlegroups.com

Well, not that difficult - you could simply enumerate all the possible anyOf/oneOf combinations, and provide the union of the allowed enum values for each one.

yes, but this already sounds way more complicated that just walking over the "properties" (and also "sub properties") object. And think of more deeply nested objects.
 
The question is how to determine that "main" is the correct field to be doing this on, but not "sub".  I mean, if you did the same calculation on "sub", then it would always show all four options.

yes, therefore I guess with my idea this should be more explicit and more easy to evaluate.
 
Ah, OK - so what you're proposing isn't intended to allow you to specify anything new.

Well, yes and no.

I think this idea wouldn't break any existing schemas, just adding another mechanism. But on the other hand, refering to a preperty is not possible right now (as opposed to refering to a schema), and it seems that it won't only allow an alternative way of structuring the schema, but also for expressing dependencies that would be difficult (if not impossible?) by only using the existing feature set. So maybe this additional possibilty would be the "new" thing.

And, it would be really only a single addition, that looks like it wouldn't be too hard to implement:

Support JSON Pointers in attributes. That's it! How exactly this is formulated is another thing, I still think a notation like this would be the most simple one:

"#/path/to/prop" : { Schema .... },

So, just resolve the left part (in essence like with $ref), evaluate schema as always and you are done ... at least, in theory ;)
 
Don't know how hard the actual implementation is, I would actually like to try this with a modified evaluator.


However, it expresses it in a way that clearly gives priority to "main", and makes "sub" clearly dependent on that.

That's... actually a pretty good way of expressing it.

Thank you! Yeah, I think this is the main point. More clear expression of both structure and especially dependencies / branches.
 

Francis's beer example is still relevant, though.  If you wrote the schema in this form, making beer type dependent on country of origin, then you make it extremely difficult to assemble a UI that allows you to specify beer type first.  This means that the schema is forcing UI decisions.

As I said, this is one thing I do not want, au contraire: the dependency does and should not work in both ways. So, no issue here ;)
 

Whereas if you used "oneOf" or other structures at the root level instead, then it doesn't prejudice towards country-first or type-first.

Yes, but what if you want to do exactly that? Maybe this is one thing that only would work with something like a "scope"?

frontend_dev

unread,
Feb 1, 2013, 9:17:06 AM2/1/13
to json-...@googlegroups.com

Sorry, I have a different view on this. It is far from being
hypothetical. If you have a schema that you _share_ with others, you
shouldn't force feed the way people use the schema.

Well, maybe there is a misunderstanding, or I still miss something, but I don't see this as a problem.

So even if I share the schema, the data(!) dependency is still there, because that is simply the way it is defined. And I still do not force the client how to present this information:

Of course, presenting dependent enums as dropdown menus would be the most intuitive way here, but this representation is not enforced at all. The dependency is what actually counts, to help the renderer to decide. Imagine I want to present both properties as <input> fields, and let the user more or less enter what they want.

Now, of course they can enter the "sub" field first in this case, but it will still throw a validation error when trying to save the form, if the user enters "food" and "water" for example.
 
What is really needed here is a DSL for forms based on JSON Schema. A
json-forms spec?

Well, I actually think this is not necessary - (almost) all I need for presenting based on a (v04) schema is already right there - except this little "missing link" that I see ;)

Francis Galiegue

unread,
Feb 1, 2013, 9:28:26 AM2/1/13
to json-...@googlegroups.com
On Fri, Feb 1, 2013 at 3:17 PM, frontend_dev <kude...@alphanull.de> wrote:
[...]
>
>>
>> What is really needed here is a DSL for forms based on JSON Schema. A
>> json-forms spec?
>
>
> Well, I actually think this is not necessary - (almost) all I need for
> presenting based on a (v04) schema is already right there - except this
> little "missing link" that I see ;)
>

I dislike two things with this solution:

* the first is that it extends the range of possible keywords to an
infinite range;
* the second is that it adds dependencies within the schema itself --
and that is a _very_ bad thing. Draft v4 has gotten rid of the only
"context dependent" keyword ("required", in the way in which is was
written), and I certainly don't want to re-introduce that kind of
dependencies. In worse.

I definitely think a DSL (written in JSON, of course) can be the way
to go. Your problem is interesting, but I don't see it being part of
the validation process (since it is not the role of validation) nor
the hyperschema (since it doesn't apply to instances).

Forms are on the "crazy idea" list currently, but your argumentation
makes this idea evolve from "crazy" to "todo". I am sure David will
give a shot at it given what JSONAry does. Right? ;)

Geraint (David)

unread,
Feb 1, 2013, 9:33:18 AM2/1/13
to json-...@googlegroups.com
Is the issue here is that you're thinking of assembling the data stage-by-stage?  As in, the user selects "main", but the data is not yet complete because they haven't entered a "sub"?

If so - the thing is that JSON Schema doesn't specify the order of construction.  It defines a set of possible JSON instance values.  It had no concept of which parts need to be entered first, it is only concerned with the final result.


On Friday, February 1, 2013 2:17:06 PM UTC, frontend_dev wrote:

Sorry, I have a different view on this. It is far from being
hypothetical. If you have a schema that you _share_ with others, you
shouldn't force feed the way people use the schema.

Well, maybe there is a misunderstanding, or I still miss something, but I don't see this as a problem.

So even if I share the schema, the data(!) dependency is still there, because that is simply the way it is defined. And I still do not force the client how to present this information:

Of course, presenting dependent enums as dropdown menus would be the most intuitive way here, but this representation is not enforced at all. The dependency is what actually counts, to help the renderer to decide. Imagine I want to present both properties as <input> fields, and let the user more or less enter what they want.

Now, of course they can enter the "sub" field first in this case, but it will still throw a validation error when trying to save the form, if the user enters "food" and "water" for example.

That's not how it would work.  What would happen is that they select "water", and the "main" field sets itself to "drink", that being the only possible option available by the dependency.

Geraint (David)

unread,
Feb 1, 2013, 9:35:01 AM2/1/13
to json-...@googlegroups.com


On Friday, February 1, 2013 1:24:52 PM UTC, frontend_dev wrote:
First of all, thanks a lot for your feedback. Let me add some comments:

While I really like the "oneOf/anyOf etc" solution, it has one major drawback imho, and that is the inability to reference parent or sibling objects. With this restriction, I am simply forced to "branch" my Schema always at the "root level", even if the actual dependency is in a deeper level.

But you can still specify what you want.

Yes, but in a (imho!) less structured and clear way.
 

I don't see the problem here, I think.  You have 10 options in "oneOf" at the top level.  How is this greatly more complicated than having 10 separate "if/then"-style structures?

Well, harder to read at least? Plus, we also want to generate the schema from the DB, so it should also be easier to construct with my alternate solution.
 

But as I said earlier - there is nothing in that "data description" that says the UI should present "main" as the primary dropdown.

Well, this might be another advantage of my proposal - there it should be quite clear what is the "primary" property.

 
 In fact, it would be simpler to present a dropdown for "sub" with the possible values "bread"/"steak"/"water"/"juice", and then simply use the value from that to determine what "main"'s value should be.

But that shouldn#
 

However, you seemed to definitely want things the other way around - "main" dropdown containing all possible options, with "sub" dropdown being filtered depending on the value of "main".  That is not a data constraint - that is a presentation constraint.

Well that is also a data constraint, isn't it?
 
In my example this is exactly what I want, because you _must_ select the main category first, or else it doesn't make sense.

The sub category selection changes _only_ if you change the main category.

Also keep in mind that there also will be default values if there wasn't a selection before - and in this special case, the UI actually has to care about correctly updating the "sub" dropdown - bit still using data from the scheme.

Even if there _shouldn't_ be any user validation errors from using this selections then, I can still use validation here to catch any programming errors.

Of course, there are many other properties in this object, and of course I want to use the schema for BOTH validation and presentation.

I totally agree.  In fact, the modular renderer system in Jsonary is tailored towards this.

Yes, I think we have similar goals ;)
 
But would you not consider it to be rendering "incorrectly" if one renderer always presented "sub" with all four options, and used them to select main?  It's back to front, but it's a valid editing interface for the data.

Yes, that would be incorrect, but I think I can avoid excatly this using my proposal.
 
Did you check the "editable" checkbox?  Otherwise it simply annotates the data with schema titles.

Ah well, yes I forgot to check that. But still, only "sub" is recognized as a dropdown.
 
Did you see the "S" button in the top left?  It should allow you to switch between the options in "oneOf"...

Geraint (David)

unread,
Feb 1, 2013, 9:48:22 AM2/1/13
to json-...@googlegroups.com
Let's look at the actual data constraints you're putting in place.  This is going to be a little bit like predicate logic

The constraints you want to put on the data are:
  • "main" is one of "food" or "drink"
  • if "main" is "food", "sub" is one of "bread" or "steak"
  • if "main" is "drink", "sub" is one of "water", "juice"

But in terms of the set of possible values that it allows, that set of constraints is completely equivalent to the following:

  • "sub" is one of "bread" or "steak" or "water" or "juice"
  • if "sub" is one of "bread" or "steak", "main" must be "food"
  • if "sub" is one of "water" or "juice", "main" must be "drink"
I hope you agree that in terms of allowed values, the above two groups are equivalent.

A human reading the first set of constraints would probably put a selector for "main" first, and then a second selector for "sub" that depends on that.

A human reading the second set of constraints would probably put a selector for "sub" first, and then calculate "main" based on that.

Now, the constraints that the schema actually define (equivalent to both the above) are:
  • the data must be exactly one of the following:
    • "sub" is one of "bread", "steak", and "main" is "food"
    • "sub" is one of "water", "juice", and "main" is "drink"
Now this has no obvious way round.  In fact, the way that Jsonary deals with this is the "S" button - which allows you to explicitly select which of the two options you are using.

What you're looking for is a way to re-phrase the same constraints (all three are completely equivalent) in a specific way (the first one) to give the form-generator additional hints about displaying the interface.

Now, if that's what you're looking for, then we can talk about that.  But I wanted to be clear exactly what you were asking for.  Does that make sense?

frontend_dev

unread,
Feb 1, 2013, 9:53:30 AM2/1/13
to json-...@googlegroups.com
Is the issue here is that you're thinking of assembling the data stage-by-stage? 

Don't know exactly what you mean by that?
 
As in, the user selects "main", but the data is not yet complete because they haven't entered a "sub"?

Well, in this case, "sub" is not even required, only if the user further wants to specify the main category.

Of course there is also a default value for both fields, if the user hasn't entered anything before.

Furthermore, if there is no main category selected yet, I could even mark "sub" as "readonly", or just limit the selection to "Please choose your Main category first" or something like this.
 

If so - the thing is that JSON Schema doesn't specify the order of construction.  It defines a set of possible JSON instance values.  It had no concept of which parts need to be entered first, it is only concerned with the final result.

Well, I am perfectly happy with that. If the order of construction really should matter, it is the concern of the view to take care of that.

But even in my example it seems this order would not really matter at all I think (see below)
 

Now, of course they can enter the "sub" field first in this case, but it will still throw a validation error when trying to save the form, if the user enters "food" and "water" for example.

That's not how it would work.  What would happen is that they select "water", and the "main" field sets itself to "drink", that being the only possible option available by the dependency.

Well, if for whatever reason the UI decides to render both fields as a simple <input> field (not a dropdown), I couldn't prevent the user from entering the "sub" field first and also independent from the main field.

But does that matter? If the user enters "food" and "steak", it will validate and all is well. If he enters "food" and "water" or "foooood" and "steak", this would simply be a validation error then. Of course in this case I would restrict selections, but just an example.

Geraint (David)

unread,
Feb 1, 2013, 10:11:14 AM2/1/13
to json-...@googlegroups.com

Well, for a non-Javascript form, unrestricted <select>s followed by a validation error is probably the only option.

I feel like I might have lost the plot somewhere here.  If it doesn't matter whether they enter "sub" or "main" first, then you can already specify everything you need using the existing spec.  I thought you were looking for a way to ensure that the user entered "main" first?

frontend_dev

unread,
Feb 1, 2013, 10:17:37 AM2/1/13
to json-...@googlegroups.com
I hope you agree that in terms of allowed values, the above two groups are equivalent.

Yes they are, but but they are expressed differently, and I like the other expression much more, due to the reasons I stated above
 

A human reading the first set of constraints would probably put a selector for "main" first, and then a second selector for "sub" that depends on that.

Yes, this is the advantage, that the constraint in the first expression is (imho) more apparent (and easier to implement), but I don't see a problem running it the other way round. In my case this would never happen anyway, and if I would ever receive wrong values from the server, I know I would have to talk to my backend guy ;) But still validation would be useful for detecting logic errors like this. Same case if I would make an error with updating the UI correctly, so even if in this special case, where the validation is not so important for the user (bc the UI actually should prevent entering wrong values) it can still help with developing.
 

A human reading the second set of constraints would probably put a selector for "sub" first, and then calculate "main" based on that.

But that also would be perfectly OK! Why not? All that does matter from my POV is that the values are valid, and easy to parse and render.

 
Now this has no obvious way round.  In fact, the way that Jsonary deals with this is the "S" button - which allows you to explicitly select which of the two options you are using.

But the user (and I) would expect that the "main" field is also rendered as a dropdown, without an additional button. But it seems that you are indeed close - nice!

 
What you're looking for is a way to re-phrase the same constraints (all three are completely equivalent) in a specific way (the first one) to give the form-generator additional hints about displaying the interface.

Yes, that would be my specific use case right now at least, with the potential solution of intruding "attribute" pointers. (and with the nice side effect of a "better" structured schema)

Again, I still think my idea will allow also open other - maybe currently unknown - possibilities and may be also useful for other purposes, since such an extension is very generic and would be not tied to any specific use.
 

Now, if that's what you're looking for, then we can talk about that.  But I wanted to be clear exactly what you were asking for.  Does that make sense?

Yes, I think so. Hope I was able to express myself clearly enough.

frontend_dev

unread,
Feb 1, 2013, 10:27:33 AM2/1/13
to json-...@googlegroups.com

Well, for a non-Javascript form, unrestricted <select>s followed by a validation error is probably the only option.

I feel like I might have lost the plot somewhere here.  If it doesn't matter whether they enter "sub" or "main" first, then you can already specify everything you need using the existing spec.  I thought you were looking for a way to ensure that the user entered "main" first?

Well, if I make "sub" readonly when nothing is selected in "main" (eg we have the default value) I can exactly do that, for example by making the 2nd selectbox read only or restrict it in other ways. But again, it is a matter of the UI to decide what exactly to do with the given data and schema.

What I really want is an alternative way to structure - or as you said: "rephrase" - "allOf" like branches, in order to help additional tools like a renderer (and also, my brain;) to better evaluate and parse the overall structure.

And completely independent of that argument I would simply prefer to "branch" schemas where it is actually needed, and not to be forced to always branch from "root". At least for me, it would be just a more elegant and clear way for expressing things like that.

Geraint (David)

unread,
Feb 1, 2013, 10:47:20 AM2/1/13
to json-...@googlegroups.com

OK, first off - I'm sorry it took me so long to understand what you were saying.

The main drawback with the proposed syntax (for me, at least) is that it is not "context-free".  At the moment, given a JSON instance and a JSON Schema, you can validate (or present a form interface, or whatever) without reference to any data outside those two arguments.  This makes validation simple to understand, simple to specify, and very simple to implement.  I don't want to lose that if I can possibly avoid it.

However... being able to more intuitively express the intention of the constraints (instead of a mathematically correct but confusing expression) is a good goal.  And there's precedent - we have {"anyOf":[A, B, ...]}, even though that can be expressed as {"not": {"allOf": [{"not": A}, {"not": B}, ...]}}.  However, I am extremely reluctant to sacrifice "context-free" validation, so I would be interested in looking at solutions that sustain that property.

Something occurs to me, though - at least for the example you gave, it would be possible to automatically present the interface you want using just the schema.  All the UI would have to do would be to notice that "main" has one distinct possible value for each entry in "oneOf", at which point it could override the default renderer and use "main" as the switcher for "oneOf".  It wouldn't work for more convoluted scenarios, but it could reliable catch the simple case - it just requires a bit more coding for the renderers.

frontend_dev

unread,
Feb 1, 2013, 10:53:06 AM2/1/13
to json-...@googlegroups.com

I dislike two things with this solution:

First of all, this is just a potential solution - the first thing that came to my head. Of course, how to exactly express that is another question.
 

* the first is that it extends the range of possible keywords to an
infinite range;

Why is this the case? All I would do is allowing for extended referencing, so there shouldn't be a single additional keyword then.

On the other hand, if you use something more explicit like "scope", there would be only _one_ additional keyword needed, right?
 
* the second is that it adds dependencies within the schema itself --
and that is a _very_ bad thing. Draft v4 has gotten rid of the only
"context dependent" keyword ("required", in the way in which is was
written), and I certainly don't want to re-introduce that kind of
dependencies. In worse.

But is something like "$rel" not also a dependency, since I can for example refer to a definition somewhere else (also in the same schema)? My proposal should do exactly the same thing - but simply not for the _value_, but the_ key_ instead.

frontend_dev

unread,
Feb 1, 2013, 10:57:59 AM2/1/13
to json-...@googlegroups.com

OK, first off - I'm sorry it took me so long to understand what you were saying.

No problem, maybe also my fault to express myself clearly enough (as a non native speaker)
 
Something occurs to me, though - at least for the example you gave, it would be possible to automatically present the interface you want using just the schema. 

Yes, I never denied that ;) But, again ...
 
 It wouldn't work for more convoluted scenarios, but it could reliable catch the simple case - it just requires a bit more coding for the renderers.

.. that's the point: more coding and problems (may even impossible) with more complex cases ;)

Francis Galiegue

unread,
Feb 1, 2013, 11:03:53 AM2/1/13
to json-...@googlegroups.com
On Fri, Feb 1, 2013 at 4:53 PM, frontend_dev <kude...@alphanull.de> wrote:
[...]
>>
>>
>> * the first is that it extends the range of possible keywords to an
>> infinite range;
>
>
> Why is this the case? All I would do is allowing for extended referencing,
> so there shouldn't be a single additional keyword then.
>
> On the other hand, if you use something more explicit like "scope", there
> would be only _one_ additional keyword needed, right?
>

There are already URI scopes defined by "id". And those are complex enough :p

>>
>> * the second is that it adds dependencies within the schema itself --
>> and that is a _very_ bad thing. Draft v4 has gotten rid of the only
>> "context dependent" keyword ("required", in the way in which is was
>> written), and I certainly don't want to re-introduce that kind of
>> dependencies. In worse.
>
>
> But is something like "$rel" not also a dependency, since I can for example
> refer to a definition somewhere else (also in the same schema)? My proposal
> should do exactly the same thing - but simply not for the _value_, but the_
> key_ instead.
>

Yes, I understand that. And "$ref" is dependent only on the URI scope.
Otherwise, it is just a plain JSON Reference.

I am still convinced that what is needed here is a DSL: there is more
than one way you want to exploit a schema. What if you wanted a form
for searching beers, for instance? Say, by country? In this case, you
need a form with only _one_ field.

frontend_dev

unread,
Feb 1, 2013, 11:16:51 AM2/1/13
to json-...@googlegroups.com

The main drawback with the proposed syntax (for me, at least) is that it is not "context-free".  At the moment, given a JSON instance and a JSON Schema, you can validate (or present a form interface, or whatever) without reference to any data outside those two arguments. 

I don't see what would change then - you'd still have the schema and the data, only the expression of dependency between 2 values is different.

I mean either way round you have to carry all relevant data. And, why not allowing relative paths and even full URIs?

In this case it would be the same with "$rel":

* for example, Paths starting with a fragment refer to a path in the same scheme
* when using a full URI, the schema can be simply loaded from the URI

of course, when referencing fails, you can spit out an error like this:

"Validation Error: invalid path to attribute: "#/my/path"


  However, I am extremely reluctant to sacrifice "context-free" validation, so I would be interested in looking at solutions that sustain that property.

Well, but what if the data - and therefore validation - actually depends on such a context? Hmm, I don't see the problem here.

frontend_dev

unread,
Feb 1, 2013, 11:44:10 AM2/1/13
to json-...@googlegroups.com

There are already URI scopes defined by "id". And those are complex enough :p

Okay, thats one thing I cannot say, because I am relatively new to this ;)
 
But at last we don't need new keywords, since "#/path" wouldn't be a keyword per se, but rather a (JSON) pointer to a keyword, big difference imho ;)


I am still convinced that what is needed here is a DSL:

Why? I think the beauty with JSON schema is that it already has everything what is needed - except for attribute referencing and even this is not absolutely needed in all cases - but makes life so much easier for certain things. (and I feel enables also things that otherwise could not be possible)

Or to put it the other way: what would be missing? Maybe the only thing I can think of tight now could be an attribute for specifying user text, like form labels, but even there you could "misuse" title or description attributes, so that is not a big point imho.
 

there is more than one way you want to exploit a schema.

Yes, and thats the job of the UI. But imho the same data - even with different UIs - should also have the same schema.

I absolutely don't see any need to specify anything explicitly presentation related in a schema - in fact this would be an anti pattern for me!
 
All I need is the structure and constraints of the data (but in a certain structured way) - and this is what JSON schema is for, right?

So, same schema for same data, no matter what the representation is - and same schema for presentation AND validation - that would be my goal.

Maximum synergies I smell here, and it feels also very DRY ;)


What if you wanted a form
for searching beers, for instance? Say, by country? In this case, you
need a form with only _one_ field.

Hmm, actually you would need two? I see a search field and a country selector here. But I don't see any problem here, especially if you have no dependencies, you can just use the existing spec. Just specify an "enum" for country selector and a simple string for the search field.

And: who says that the UI _must_ display a certain value? Of course you could also work with "hidden" values. Again - imho! - it is up to the UI to decide what is rendered in what way.

Chris Miles

unread,
Feb 1, 2013, 1:54:45 PM2/1/13
to json-...@googlegroups.com
I wonder if adding another constraint to the schema would do it.

Perhaps use allOf with the first providing the enum choice and the second constraining main values to sub enums?

{
  "type" : "object",
  "required" : ["main", "sub"],
  "allOf" : [
    {
      "type" : "object",
      "properties" : {
        "main" : { "enum" : [ "food", "drinks" ] }
      }
    },
    {
       "type" : "object",
       "oneOf" : [
           {
            "title": "Food menu",

            "properties" : {
              "main":{"enum" : ["food"]},
              "sub":{"enum" : ["bread", "steak"]}
            }
          },
         {
            "title":"Drink menu",

            "properties":{
              "main": {"enum" : ["drinks"]},
              "sub": {"enum" : ["water", "juice"]}     
            }
          }
       ]
     }
  ]

frontend_dev

unread,
Feb 1, 2013, 2:12:42 PM2/1/13
to json-...@googlegroups.com

Am Freitag, 1. Februar 2013 19:54:45 UTC+1 schrieb Chris Miles:
I wonder if adding another constraint to the schema would do it.

On a first glance, I feel that it would be even more complex to parse such a structure.

Plus, it still does not solve the problem that the overal structure is "torn apart" then, with everything still branching from root.

Francis Galiegue

unread,
Feb 1, 2013, 2:19:08 PM2/1/13
to json-...@googlegroups.com
On Fri, Feb 1, 2013 at 8:12 PM, frontend_dev <kude...@alphanull.de> wrote:
[...]
>
> On a first glance, I feel that it would be even more complex to parse such a
> structure.
>
> Plus, it still does not solve the problem that the overal structure is "torn
> apart" then, with everything still branching from root.
>

This is not the problem. At least, not the general problem.

There _is_ more than one way to express the same set of constraints
using JSON Schema. All ways are equal, there cannot be one way "more
equal" than another one.

I stil fail to see how your use case cannot be satisfied by carrying
context information with you when you generate a UI. But this context
information, imho, has not its place in JSON Schema.

frontend_dev

unread,
Feb 1, 2013, 3:01:45 PM2/1/13
to json-...@googlegroups.com
This is not the problem. At least, not the general problem.

But at least my problem when it comes to analysing and parsing a schema ;)

There _is_ more than one way to express the same set of constraints
using JSON Schema. All ways are equal, there cannot be one way "more
equal" than another one.

Of course, I am perfectly fine with that. In fact I see such an extension wouldn't break anything that exists, if somebody wants to branch at the root level, of course he can do that. In fact, both solutions should validate in an identical way, the schema is just structured / formulated differently with each solution.

I stil fail to see how your use case cannot be satisfied by carrying
context information with you when you generate a UI.

In my eyes, the schema IS the context, and in most of the cases that's really all that is needed for being able to present such information.

Why adding more additional information that is not really needed or just a duplicate of already existing things? The main problem is to express the context in a more suitable way for parsing. With the current solution it is still very hard to even get the concrete values of my "main" property, and I also NEED this values for displaying my dropdown. So should I really duplicate everything, and use a second dataset for just defining what "main" is? But that was already done! All I would do is replicate this info, maybe in a more suitable way. But this will quickly become a PITA and is completely un-DRY and almost an anti pattern imho.

Well, yes I also can start defining and implementing a whole new system just for rendering, but I am sure I will end up with a format that is more or less identical to a JSON schema. So why shouldn't I use this Information if it is already there? I feel that JSON Schema was only designed for validation? I would dare to say: you can do more than that with a schema, and it is perfectly suited for presenting data ;)

 
But this context information, imho, has not its place in JSON Schema.

Well, what context that I would need for presenting is actually missing from the schema spec? I am only talking about data specific context - of course, client and UI specific context (like colors and fonts) has no place in a schema, there I totally agree. But that is something I explicitly want to avoid anyway.

Francis Galiegue

unread,
Feb 1, 2013, 3:08:54 PM2/1/13
to json-...@googlegroups.com
On Fri, Feb 1, 2013 at 9:01 PM, frontend_dev <kude...@alphanull.de> wrote:
[...]
>
> Well, yes I also can start defining and implementing a whole new system just
> for rendering, but I am sure I will end up with a format that is more or
> less identical to a JSON schema. So why shouldn't I use this Information if
> it is already there? I feel that JSON Schema was only designed for
> validation? I would dare to say: you can do more than that with a schema,
> and it is perfectly suited for presenting data ;)
>

I never said that JSON Schema was only for validation :p I'll eat my
own dog food anyway when I'm done rearchitecturing my project since
the next step will be... Yes... Form generation. I'll probably get a
more solid grasp of what can be done by then ;)

frontend_dev

unread,
Feb 1, 2013, 4:03:25 PM2/1/13
to json-...@googlegroups.com

The main drawback with the proposed syntax (for me, at least) is that it is not "context-free".  [...]  I don't want to lose that if I can possibly avoid it.

Ok, after banging my head for several hours on this topic I think I have another idea in addition that might be clear the scene a bit more.

I realised that the point is not really about referencing some attribute in the schema itself - maybe this was a bit misleading - no, it is more about referencing the properties alone and therefore actually referencing the data. So, how about something like this:

"$data" : "..."

similar to:

"$rel" : "..."

Instead of evaluating the object hierarchy to get a data value based on its own internal "property" structure, I would just have to use the path after "$data" (or whatever) therefore and get the value from there (if there is one) and then continue validating the connected subscheme as usual - whatever the syntax will look like, at least if it doesn't branch from root ;)

And then ... by supporting full URIs ... you could also validate a scheme by combining data from several sources, right?

Does that sound better?

Austin Wright

unread,
Feb 1, 2013, 9:45:45 PM2/1/13
to json-...@googlegroups.com
Apologies in advance if this back-tracks on any already highly-debated points, but it seems like the solution is clear. So first allow me to re-phrase your question:

You would like to generate a form with two selection elements (select, radio set, or similar), where the range of valid choices of a second element is dictated by the selection of the first; and you would like to use a schema to validate the options submitted to the form; and you would like to generate this form using that same schema.

There's multiple valid ways of specifying this schema for validation, but the simplest is probably the correct one (ECMAScript notation for brevity):

{ type: "object"
, properties: {main: {enum: ["drinks","food"]}}
, oneOf:
    [ {properties: {main: {enum:["drinks"]}, sub: {enum:["juice", "water"]} }}
    , {properties: {main: {enum:["food"]}, sub: {enum:["bread", "steak"]} }}
    ]
}

However, that said, this may not be a job for JSON Schema. Or, this may not be a job for JSON Schema alone. You could try and build a form generator using this schema, but you may be forcing semantics out of the schema when they don't really exist. But it certainly is possible that you can examine the schema, link up properties to existing HTML fields, observe that the second value depends only on the value of the first (and is not therefore cyclical) and hide illegal values from the second select box.

But again, this may not carry the intended semantics. You may want to extend the schema with your own vocabulary that hints at what form element to use. I do this in my program with a "widget" property. You could create your own JSON vocabulary, and use a simple script to produce the more complex JSON Schema vocabulary that you see above from your vocabulary.

And with that solution demonstrating that it is possible, consider that your UI scheme may simply be broken. Why not a single select element and a tree design? That's what the HTML <optgroup/> is for.

You probably want to specify and attach a data source to your form that looks similar to e.g.:

[ {main: "drinks", sub:"water"}
, {main: "drinks", sub:"juice"}
, {main: "food", sub:"bread"}
, {main: "food", sub:"steak"}
]

And from this you can produce a single elements or multiple select elements as necessary.

This would also be very easy to convert into a schema, just place it in verbatim: {oneOf: [...]}

On Saturday, January 19, 2013 9:12:09 AM UTC-7, frontend_dev wrote:
Hello!

First of all, I know that some similar questions were already asked, but I am still struggling, so I hope you can enlighten me a bit:

In my project, I need to ask the user about two categories, let's call them "main" and "sub". The "main" category is just an enum with a predefined set of values. Since I also want to include a title in the schema, I ended up with something like this:

"main" : {
  "type" :[ 
     {"enum" : ["main1"], title :"main1 title"},
     {"enum" : ["main2"], title :"main2 title"},
     {"enum" : ["main3"], title :"main3 title"}
  ]
}

Now, if the user selects a main category, he can also enter a sub category, but this depends on the main category!

Based on the selection in "main", I want to

a) Present (and validate) a certain matching sub category - OR -
b) Prevent the user from entering ANY sub category, if ONLY a main category exists (not all main categories actually have defined sub categories) - OR -
c) Prevent the user from entering ANY sub category, if a main category hasn't been selected yet

Now, as I watched the former diskussions I understand that v4 of the draft would solve this quite differently to v3. Since I am not sure what validator I will use later, and since not all validators support v4 yet, how would I do this:

* in v3?
* in v4?

Or would you actually recomment to go straight to v4 nonetheless?

Any help is greatly appreciated, thank you in advance!

Geraint (David)

unread,
Feb 2, 2013, 4:27:03 AM2/2/13
to json-...@googlegroups.com
That's a very interesting idea - I'll think about it more.

Schemas can always be embedded in other schemas (data inclusion) to create "composite" data formats.  This would break if your "$data" property included an absolute path relative to the document root - it would need to be a relative one, for which no syntax currently exists.

You open the possibility of tying yourself in knots (you could reference the data's parent and the schemas parent, and it would just go around in circles), but you can already do that in other ways.

Geraint (David)

unread,
Feb 2, 2013, 4:33:31 AM2/2/13
to json-...@googlegroups.com


On Friday, February 1, 2013 7:19:08 PM UTC, fge wrote:
On Fri, Feb 1, 2013 at 8:12 PM, frontend_dev <kude...@alphanull.de> wrote:
[...]
>
> On a first glance, I feel that it would be even more complex to parse such a
> structure.
>
> Plus, it still does not solve the problem that the overal structure is "torn
> apart" then, with everything still branching from root.
>

This is not the problem. At least, not the general problem.

There _is_ more than one way to express the same set of constraints
using JSON Schema. All ways are equal, there cannot be one way "more
equal" than another one.

I stil fail to see how your use case cannot be satisfied by carrying
context information with you when you generate a UI. But this context
information, imho, has not its place in JSON Schema.

I think the issue here is that in many cases, the JSON Schema vocabulary lets you express the constraints in an intuitive way.  "Intuitive" generally means "matches the intention of the constraints" - this can be used to assemble appropriate UIs, but other benefits include ease of reading and writing.

So in a way, we could completely forget about the UI requirement for a moment, and say that the underlying issue being raised is "the syntax for interdependencies between variables is not intuitive and readable".

(frontend_dev - does that sound OK to you?)

frontend_dev

unread,
Feb 2, 2013, 9:37:10 AM2/2/13
to json-...@googlegroups.com
Apologies in advance if this back-tracks on any already highly-debated points, but it seems like the solution is clear. So first allow me to re-phrase your question:

You would like to generate a form with two selection elements (select, radio set, or similar), where the range of valid choices of a second element is dictated by the selection of the first; and you would like to use a schema to validate the options submitted to the form; and you would like to generate this form using that same schema.

 Well, I would go one step further:

I would like to have a mechanism where I not only can reference to a schema (using $rel) but also to the underlying data.

This would be a very basic extension which will also help to solve parsing schemas, but as we see it could also be used for more, for example validating against several independent data sources, and of course this referenced data doesn't have to be the original data object.

For example you could take your data and validate against some output of say a remote web service (of course the returned data has to be a valid JSON object)

You also could use just a only schema  for validation - by referencing a remote data object within that schema.

frontend_dev

unread,
Feb 2, 2013, 9:40:14 AM2/2/13
to json-...@googlegroups.com
So in a way, we could completely forget about the UI requirement for a moment, and say that the underlying issue being raised is "the syntax for interdependencies between variables is not intuitive and readable".

Actually as I posted just above I would go one step further! The proposal would of course also improve readability, but this is just one side effect of the proposed solution (whatever it will look like in the end)

Also, the "old" syntax would still be perfectly valid, so we could choose whatever expression is more suitable.

frontend_dev

unread,
Feb 2, 2013, 9:49:02 AM2/2/13
to json-...@googlegroups.com
Schemas can always be embedded in other schemas (data inclusion) to create "composite" data formats.  This would break if your "$data" property included an absolute path relative to the document root - it would need to be a relative one, for which no syntax currently exists.

That is one thing I do not understand: What is "an absolute path relative to the document root" ?

I still think of something like JSON Pointers, so this could be simply something like this:

"#/property/subproperty"

That would be an absolute path from document (or better "data root", since it is crucial to know that this pointer does NOT point to a schema, but the underlying data instead).

So, my data object could look like this:

{
   "property" : {
        "subproperty" :  "value"
   }
}


and the path would resolve to "value".

A real relative path could look like this:

"../../"

So this could be resolved from the current data path (resolved from the schemas "property" tree)

And why not supporting full URIs? In this case, we would just load the data from a remote source, just like with external schemes.


You open the possibility of tying yourself in knots (you could reference the data's parent and the schemas parent, and it would just go around in circles), but you can already do that in other ways.

Yes, if I want, I can break everything, or write schemas that never validate ;) So I don't know if this is a real issue.

frontend_dev

unread,
Feb 2, 2013, 9:52:40 AM2/2/13
to json-...@googlegroups.com
And, what I also like to see in the syntax is a way to connect a reference to data with a reference to a schema for maximum power and flexibility.


Austin Wright

unread,
Feb 3, 2013, 8:11:24 AM2/3/13
to json-...@googlegroups.com
On Saturday, February 2, 2013 7:37:10 AM UTC-7, frontend_dev wrote:

 Well, I would go one step further:

I would like to have a mechanism where I not only can reference to a schema (using $rel) but also to the underlying data.

This would be a very basic extension which will also help to solve parsing schemas, but as we see it could also be used for more, for example validating against several independent data sources, and of course this referenced data doesn't have to be the original data object.

For example you could take your data and validate against some output of say a remote web service (of course the returned data has to be a valid JSON object)

You also could use just a only schema  for validation - by referencing a remote data object within that schema.

So you'd like a vocabulary which can do something like this: A schema is a set of instructions that must all validate to return valid. Introduce an instruction that validates some other instance elsewhere against a given schema.

I can't imagine this being necessary in JSON Schema. I believe one can prove that for every possible way you could use this instruction, you can also build a schema that works with existing instructions (properties).

I mean, I can't see any reason to be against this exactly, and there's nothing wrong with introducing features that simplify a schema document, but be aware it would require a radical re-design of how schemas are currently understood, processed, and written, given their current status as being context-free.

It may be arbitrary, or hopefully at least economically calculated, but at some point one would say "almost no one would use that feature, the cost far exceeds the benefit, therefore that's out of scope of JSON Schema (but feel free to extend the functionality with your own custom property)." (Imagine e.g. a property that ensures two coordinates are within a certain distance of each other. That's perfectly valid, but why would that ever be worth the cost.)

So I'm inclined to maintain that this is outside the scope of JSON Schema by itself.

Geraint Luff

unread,
Feb 3, 2013, 8:57:58 AM2/3/13
to json-...@googlegroups.com
On 3 February 2013 13:11, Austin Wright <diamon...@users.sourceforge.net> wrote:
On Saturday, February 2, 2013 7:37:10 AM UTC-7, frontend_dev wrote:

 Well, I would go one step further:

I would like to have a mechanism where I not only can reference to a schema (using $rel) but also to the underlying data.

This would be a very basic extension which will also help to solve parsing schemas, but as we see it could also be used for more, for example validating against several independent data sources, and of course this referenced data doesn't have to be the original data object.

For example you could take your data and validate against some output of say a remote web service (of course the returned data has to be a valid JSON object)

You also could use just a only schema  for validation - by referencing a remote data object within that schema.

So you'd like a vocabulary which can do something like this: A schema is a set of instructions that must all validate to return valid. Introduce an instruction that validates some other instance elsewhere against a given schema.

I can't imagine this being necessary in JSON Schema. I believe one can prove that for every possible way you could use this instruction, you can also build a schema that works with existing instructions (properties).

Absolutely.  This is why I was trying to approach the question from the angle of "the syntax for interdependencies between variables is not intuitive and readable". Not impossible, or incomplete, but unintuitive.
 
I mean, I can't see any reason to be against this exactly, and there's nothing wrong with introducing features that simplify a schema document, but be aware it would require a radical re-design of how schemas are currently understood, processed, and written, given their current status as being context-free.

I agree - it would change some quite fundamental properties, and we shouldn't do it lightly.
 
It may be arbitrary, or hopefully at least economically calculated, but at some point one would say "almost no one would use that feature, the cost far exceeds the benefit, therefore that's out of scope of JSON Schema (but feel free to extend the functionality with your own custom property)." (Imagine e.g. a property that ensures two coordinates are within a certain distance of each other. That's perfectly valid, but why would that ever be worth the cost.)

So I'm inclined to maintain that this is outside the scope of JSON Schema by itself.

I think "out of scope" doesn't quite fit your argument.  "Not worth the cost" seems to be a better summary of what you're saying.

I think that's definitely the discussion we should be having - is it worth it?  It would be occasionally useful for me personally, but it is a big change.

frontend_dev

unread,
Feb 3, 2013, 11:15:02 AM2/3/13
to json-...@googlegroups.com

So you'd like a vocabulary which can do something like this: A schema is a set of instructions that must all validate to return valid. Introduce an instruction that validates some other instance elsewhere against a given schema.

Basically, yes. Instead of "elsewhere" one could say: "that validates ANY instance against a given schema" (not only restricted to properties of the current  scope)
 
I can't imagine this being necessary in JSON Schema. I believe one can prove that for every possible way you could use this instruction, you can also build a schema that works with existing instructions (properties).

Ok, so given only the existing solution, how do you:

- express a dependency that does not need to "start from root" if you want to compare to a sibling property
- create a schema that can be easily analyzed by a human _or_ piece of code, for example in order to evaluate what concrete schema one given property has
- create a schema where it can be easily evaluated what dependencies actually apply

and:

- create a schema that allows to validate a given instance against a value from another instance. For example you need to validate a piece of data against some data that resides on a remote URI. Not possible right now imho.
 

I mean, I can't see any reason to be against this exactly, and there's nothing wrong with introducing features that simplify a schema document, but be aware it would require a radical re-design of how schemas are currently understood, processed, and written, given their current status as being context-free.

I also don't think that the redesign would be "radical". It is imho not even a redesign, since nothing that already exists has to be changed or would break, not need for rewriting anything, since the way of expressing dependencies is still "anyOf", "oneOf" etc. Even the way a validating algorithm works is absolutely the same, there is in fact only _one_ difference I see when it comes to accessing the actual values we validate aginst:

Instead of evaluating the concrete data value based on the property structure of the schema (and therefore essentially limiting branches to "sub-properties"  only) the validator just has to get the value from a specified path or let's better say: URI (absolute or relative) and "feed" the schema with the result derived from there instead. The actual validation should not change, just the value/object it is compared against.
 
Of course, I might miss something, but I still do not see anything ;) In fact it _seems_ so easy, that I'd like to simply try it out.

frontend_dev

unread,
Feb 3, 2013, 11:23:46 AM2/3/13
to json-...@googlegroups.com

Absolutely.  This is why I was trying to approach the question from the angle of "the syntax for interdependencies between variables is not intuitive and readable". Not impossible, or incomplete, but unintuitive.

I absolutely agree! This was the original source of the problem and more intuitivity would be one of the main benefits.

Another one would be the possibility of validating against multiple data sources. This also looks interesting to me.
 

 I agree - it would change some quite fundamental properties, and we shouldn't do it lightly.

Still think it is not _that_ fundamental ;)

I mean: what else would it change beside adding another way of accessing the data values a schema is validated against?

Geraint Luff

unread,
Feb 4, 2013, 5:04:01 AM2/4/13
to json-...@googlegroups.com
Currently, all you need to validate schemas at the moment is a validation function and a global schema lookup function.

The global schema lookup function takes in a URL, and returns a schema.  The validation function takes in data and a schema, and returns some measure of validity.

The validation function can behave recursively on those two arguments - the data and the schema.  If it encounters a $ref, then it uses the global validation function and continues.

For example, take these two schema/data pairs:
Schema 1:
{
    "type": "array",
    "items": {  ... whatever ... }
}
Data 1:
[
    {"foo": "bar"}
]

Schema 2:
{ ... whatever ... }
Data 2:
{"foo": "bar"}

Currently, a recursive validation algorithm dealing with the first pair will call back to itself when dealing with the array contents.  At this point the function call is completely equivalent to the function call for validating the second pair.  This is what is meant by "context free" - it relies on the relevant schema and the relevant data itself, and is not affected at all by the parent schema or the parent data.

This property allows for shorter, more efficient and more elegant implementations of the validator.

But if the schema can reference other parts of the data tree, then it suddenly does matter what the parent schema or the parent data is.  Does that help?  I'm sorry if I'm not explaining this clearly...

frontend_dev

unread,
Feb 4, 2013, 10:10:23 AM2/4/13
to json-...@googlegroups.com
Currently, all you need to validate schemas at the moment is a validation function and a global schema lookup function.

The global schema lookup function takes in a URL, and returns a schema.  The validation function takes in data and a schema, and returns some measure of validity.

Yes, and the "Data lookup function" takes in a URL, and returns a value. That is still the one and only main change I see.
 
Currently, a recursive validation algorithm dealing with the first pair will call back to itself when dealing with the array contents.  At this point the function call is completely equivalent to the function call for validating the second pair.  This is what is meant by "context free" - it relies on the relevant schema and the relevant data itself, and is not affected at all by the parent schema or the parent data.

Well, until you encounter "$rel" - in this case it would be affected, right?
 

But if the schema can reference other parts of the data tree, then it suddenly does matter what the parent schema or the parent data is.  Does that help?  I'm sorry if I'm not explaining this clearly...

Maybe I also do not "get it" completely, also sorry for that ;)

So why would the parent schema matter if I had something like "$data"? The parent data, (or even another instance) of course would be affected here, but this is something I want, bc these dependencies simply do exist and are simply required. But the schema it would be validated against is still context free .... or?

I mean, if you had a syntax like this:

"$data:#/main" : { "enum" : ["drinks"]}

it would be still the schema on the right hand side that is evaluated just if I had written something like this:

{
   "properties" : {

         "main" : { "enum" : "drinks" }
  }
}


btw if I write something like this, it should be equivalent to the code right above:

{
   "properties" : {

        
"$data:#/main" : { "enum" : "drinks" }
  }
}


(Only an example, of course how the syntax should look like is another question, just to make it clearer)

But you can see that only the "blue" code (path to the data) changes, but not the "green" one (the schema the value is validated against)

With the original solution, the path to the data is always evaluated (implicitly) based on the schemas property structure whereas in the example above, the validator just has to evaluate the given (explicit) path. But I still don't see what changes else.

Same schema, only the value it is compared against changes. So context of the data matters here (and is intended!), but not the context of the schema, right? Or am I still missing something here?
 
Of course if you would write:

{
   "properties" : {

        
"$data:http://somewhere/else" : { "$rel" : "http://somewhere/else" }
  }
}


Then both data and schema wouldn't be context free - but that's the way it would be simply defined and required then. Do I understand this correctly?

Plus, this example wouldn't be possible with only the existing solution. Or to put in other words: how would you work without context, when this context simply exists, and is even required? I think for many more complex cases these dependencies exist as a matter of fact - even in my form I work right now, there is another dependency apart from the two "enums".

Geraint Luff

unread,
Feb 4, 2013, 10:17:47 AM2/4/13
to json-...@googlegroups.com
On 4 February 2013 15:10, frontend_dev <kude...@alphanull.de> wrote:
Currently, all you need to validate schemas at the moment is a validation function and a global schema lookup function.

The global schema lookup function takes in a URL, and returns a schema.  The validation function takes in data and a schema, and returns some measure of validity.

Yes, and the "Data lookup function" takes in a URL, and returns a value. That is still the one and only main change I see.
 
Currently, a recursive validation algorithm dealing with the first pair will call back to itself when dealing with the array contents.  At this point the function call is completely equivalent to the function call for validating the second pair.  This is what is meant by "context free" - it relies on the relevant schema and the relevant data itself, and is not affected at all by the parent schema or the parent data.

Well, until you encounter "$rel" - in this case it would be affected, right?
 

But if the schema can reference other parts of the data tree, then it suddenly does matter what the parent schema or the parent data is.  Does that help?  I'm sorry if I'm not explaining this clearly...

Maybe I also do not "get it" completely, also sorry for that ;)

So why would the parent schema matter if I had something like "$data"? The parent data, (or even another instance) of course would be affected here, but this is something I want, bc these dependencies simply do exist and are simply required. But the schema it would be validated against is still context free .... or?

I mean, if you had a syntax like this:

"$data:#/main" : { "enum" : ["drinks"]}

it would be still the schema on the right hand side that is evaluated just if I had written something like this:

{
   "properties" : {

         "main" : { "enum" : "drinks" }
  }
}


btw if I write something like this, it should be equivalent to the code right above:

{
   "properties" : {

        
"$data:#/main" : { "enum" : "drinks" }
  }
}


 
Not 100%, I think...

If you assume that the schema(s) above have the URI "/schemas/alphanull_example", then how about the following two schemas:
{
    "allOf": [{"$ref": "/schemas/alphanull_example"}]
}
and
{
    "items": {"$ref": "/schemas/alphanull_example"}
}

The first of those two would indeed behave the same way with either of your example schemas.  The second, however, would behave differently - because the fragment reference in your second example would no longer be a path relative to the object of interest, but the array containing it.

It seems to me like it causes problems if you want to later embed that data format inside another data format (e.g. an array of such instances).
 
(Only an example, of course how the syntax should look like is another question, just to make it clearer)

But you can see that only the "blue" code (path to the data) changes, but not the "green" one (the schema the value is validated against)

With the original solution, the path to the data is always evaluated (implicitly) based on the schemas property structure whereas in the example above, the validator just has to evaluate the given (explicit) path. But I still don't see what changes else.

Same schema, only the value it is compared against changes. So context of the data matters here (and is intended!), but not the context of the schema, right? Or am I still missing something here?
 
Of course if you would write:

{
   "properties" : {

        
"$data:http://somewhere/else" : { "$rel" : "http://somewhere/else" }
  }
}


Then both data and schema wouldn't be context free - but that's the way it would be simply defined and required then. Do I understand this correctly?

Plus, this example wouldn't be possible with only the existing solution. Or to put in other words: how would you work without context, when this context simply exists, and is even required? I think for many more complex cases these dependencies exist as a matter of fact - even in my form I work right now, there is another dependency apart from the two "enums".

That's pretty cool functionality - but we've now made a jump from validating an instance, to validating an entire network of instances at different locations.  I haven't seen a huge demand for that functionality, and it doesn't seem to fit with the rest of the purpose of JSON Schema - although it is pretty cool.

Geraint (David)

unread,
Feb 4, 2013, 10:53:50 AM2/4/13
to json-...@googlegroups.com
OK - here's an idea I've been kicking around.  This is not very detailed, but I was exploring it because I think it would make hyper-schemas immensely more powerful.

The idea was that templating from the data might be useful in more places than just "href".  I was thinking that maybe "rel", probably "mediaType" as well, would be able to specify that their value should be templated.

A possible syntax might be something like:  (this is an LDO):
{
    "href": ...,
    "rel": {"template": "{rel}"},
    "mediaType": {"template": "{type}"}
}
So we could take not just the URI, but also the rel/mediaType/etc. from the data.  This means that we would be able to fully document existing formats such as HAL which include the link definitions (including rel/mediaType, etc) in the data.

It would also be an obvious place to implement more powerful templating, such as:
{
    "rel": "author",
    "href": {
        "template": "/authors/{primaryAuthor}",
        "vars": {
            "primaryAuthor": "/authors/primary"
        }
    }
}
The values in "vars" would be JSON Pointer paths - so you could template using data that was beyond the immediate instance, down to grandchildren, etc.

So how is this relevant to the discussion here?  Well, I was wondering what would happen if we allowed that syntax to template the value of "$ref":
{
    "type": "object",
    "properties": {
        "main": {"enum": ["food", "drink"]}
    },
    "allOf": [{
        "$ref": {
            "template": "#/subOptions/{main}"
        }
    }],
    "subOptions": {
        "food": {
            "properties": {
                "sub": {"enum": [...]}
            }
        },
        "drink": {
            "properties": {
                "sub": {"enum": [...]}
            }
        }
    }
}
The idea is that when we change the value of "main", the target of the "$ref" changes, and therefore a different set of constraints apply.

It's a pretty wild idea to use it for "$ref" - I was intending it mainly for use within LDOs, where I think it makes more sense, and could do a lot of good.  But I thought I'd mention it.

On Monday, February 4, 2013 3:17:47 PM UTC, Geraint (David) wrote:
To unsubscribe from this group and stop receiving emails from it, send an email to j...@googlegroups.com.

frontend_dev

unread,
Feb 4, 2013, 11:38:48 AM2/4/13
to json-...@googlegroups.com

The first of those two would indeed behave the same way with either of your example schemas.  The second, however, would behave differently - because the fragment reference in your second example would no longer be a path relative to the object of interest, but the array containing it.

Hmm, maybe I do not get it, but your example seems more related to "$rel" ? I don't see where "$data:" - and potential problems with that proposal - do fit here.

Can you elaborate more on your example, maybe with a hypothetical "$data" attribute like drafted above?

Of course it would be important to catch any existing "gotchas" with this proposal beforehand. But still, at least I still don't see the "big issue" yet.

 
It seems to me like it causes problems if you want to later embed that data format inside another data format (e.g. an array of such instances).

Does it only seem so or is it a defintive issue? That would be the question.

 
That's pretty cool functionality - but we've now made a jump from validating an instance, to validating an entire network of instances at different locations. 

Yes, I think that is very interesting indeed. And why not? This would open many additional possibilities - like with my example where you can validate some data based on the presence or value of another piece of data - and in the same object or not should not matter, so yes: I would support full URIs there - just like with "$rel".

 
I haven't seen a huge demand for that functionality,

Yes .... until now! But often, demand comes only after opening a new way of doing things, and here we have something that simply was not possible before.

I think that this could be very useful also for other things ... even things someone just hadn't thought about before ;)

What I also like is that the proposed solution would solve several problems at once, and that without being tied to a single usecase, so a benefit like being able to better parse a schema is only ONE of the advantages.


and it doesn't seem to fit with the rest of the purpose of JSON Schema

here I have to strongly disagree ;)

Imho it does not only fit _perfectly_  in the existing way of doing things, I would go even further and say that it also seems to me that this is even a kind of "gap" or "missing link" in the whole spec!

I mean: why can you reference other schemas, but not other data? Why is data access so severly limited in contrast to scheme access? You have branching, via "anyOf" etc, but why this is limited only to "subproperties" of the instance I am looking at? It just feels incomplete to me. Therefore, the need to "branch from root" is for me basically still simply a more or less awkward workaround for this limitation - if you can't reference to parents/siblings, you need to build up the whole structure from the ground up in _each_ of your branches. I just have to because it does not work any other way. That just feels not right.

So, without that possibility, I feel that something really essential is missing. And still I see "$data:" just as a kind of (missing) "sister function" to "$rel".

Therefore, with that mechanism, you could refer to "both sides of the equation" then, and not only to the schema.

Geraint Luff

unread,
Feb 4, 2013, 11:43:01 AM2/4/13
to json-...@googlegroups.com
On 4 February 2013 16:38, frontend_dev <kude...@alphanull.de> wrote:

The first of those two would indeed behave the same way with either of your example schemas.  The second, however, would behave differently - because the fragment reference in your second example would no longer be a path relative to the object of interest, but the array containing it.

Hmm, maybe I do not get it, but your example seems more related to "$rel" ? I don't see where "$data:" - and potential problems with that proposal - do fit here.

Can you elaborate more on your example, maybe with a hypothetical "$data" attribute like drafted above?

I was attempting to re-use your example.  My issue is with what happens when a schema containing "$data" is referenced from another schema.  In the example, I was using your existing examples from just above where I made my comment, and referencing them from separate examples of my own.

Does that make sense?
 
Of course it would be important to catch any existing "gotchas" with this proposal beforehand. But still, at least I still don't see the "big issue" yet.

 
It seems to me like it causes problems if you want to later embed that data format inside another data format (e.g. an array of such instances).

Does it only seem so or is it a defintive issue? That would be the question.

 
That's pretty cool functionality - but we've now made a jump from validating an instance, to validating an entire network of instances at different locations. 

Yes, I think that is very interesting indeed. And why not? This would open many additional possibilities - like with my example where you can validate some data based on the presence or value of another piece of data - and in the same object or not should not matter, so yes: I would support full URIs there - just like with "$rel".

 
I haven't seen a huge demand for that functionality,

Yes .... until now! But often, demand comes only after opening a new way of doing things, and here we have something that simply was not possible before.

I think that this could be very useful also for other things ... even things someone just hadn't thought about before ;)

What I also like is that the proposed solution would solve several problems at once, and that without being tied to a single usecase, so a benefit like being able to better parse a schema is only ONE of the advantages.


and it doesn't seem to fit with the rest of the purpose of JSON Schema

here I have to strongly disagree ;)

Imho it does not only fit _perfectly_  in the existing way of doing things, I would go even further and say that it also seems to me that this is even a kind of "gap" or "missing link" in the whole spec!

I mean: why can you reference other schemas, but not other data? Why is data access so severly limited in contrast to scheme access? You have branching, via "anyOf" etc, but why this is limited only to "subproperties" of the instance I am looking at? It just feels incomplete to me. Therefore, the need to "branch from root" is for me basically still simply a more or less awkward workaround for this limitation - if you can't reference to parents/siblings, you need to build up the whole structure from the ground up in _each_ of your branches. I just have to because it does not work any other way. That just feels not right.

So, without that possibility, I feel that something really essential is missing. And still I see "$data:" just as a kind of (missing) "sister function" to "$rel".

Therefore, with that mechanism, you could refer to "both sides of the equation" then, and not only to the schema.

--

frontend_dev

unread,
Feb 4, 2013, 11:52:39 AM2/4/13
to json-...@googlegroups.com

So how is this relevant to the discussion here?  Well, I was wondering what would happen if we allowed that syntax to template the value of "$ref":
{
    "type": "object",
    "properties": {
        "main": {"enum": ["food", "drink"]}
    },
    "allOf": [{
        "$ref": {
            "template": "#/subOptions/{main}"
        }
    }],
    "subOptions": {
        "food": {
            "properties": {
                "sub": {"enum": [...]}
            }
        },
        "drink": {
            "properties": {
                "sub": {"enum": [...]}
            }
        }
    }
}
The idea is that when we change the value of "main", the target of the "$ref" changes, and therefore a different set of constraints apply.

Hmm but I still think it would be not too easy to parse. Maybe even harder now to evaluate what "sub" actually is.

In contrast, what about this:

{
    "type": "object",
    "properties": {
        "main": {"enum": ["food", "drink"]},
        "sub" : {
          "oneOf" : [
            {
               "$data:#/main" : { "enum" : ["food"] },
               "enum" : ["steak, "bread"]   
            },

            {
               "$data:#/main" : { "enum" : ["drinks"] },
               "enum" : ["water, "juice"]   
            }
         ]
      }
    }

}

Looks less convoluted, more explicit and way easier to evaluate as the example above - at least for me.

the algorithm then could basically look like this:

1) If the validator encounters an attribute beginning with "$data:", it must evaulate the value resulting from the given path
2) The value for "$data:...." itself (in the schema) MUST be a schema
3) Validate the value with the given schema, as always

Geraint Luff

unread,
Feb 4, 2013, 11:57:48 AM2/4/13
to json-...@googlegroups.com
But the "given path" is a JSON Pointer path, which means that the data being verified must exist at a particular position relative to the document root for this schema to work.

What if you define your format as above, but then I want to submit/validate a list of such instances, or I want to describe a map from restaurant visitors to their menu choices?  A JSON Pointer fragment would no longer point at the correct place.
 
--
You received this message because you are subscribed to the Google Groups "JSON Schema" group.
To unsubscribe from this group and stop receiving emails from it, send an email to json-schema...@googlegroups.com.

frontend_dev

unread,
Feb 4, 2013, 12:03:01 PM2/4/13
to json-...@googlegroups.com
I was attempting to re-use your example.  My issue is with what happens when a schema containing "$data" is referenced from another schema.  In the example, I was using your existing examples from just above where I made my comment, and referencing them from separate examples of my own.

Does that make sense?

So you mean what happens if you "$rel" to another schema, and this one in turn contains a "$data:" attribute, maybe even with a relative link?

OK, I think I see your point, but is it actually a problem?

Am I right when I say that with a linked schema, the data it applies to remains the same, only the schema is replaced?

So, if I would have  "$data:#/relative/path" in this linked schema, the path would still apply to the "original" data object (the one the originating schema was fed with)

Does that also make sense? 

Geraint Luff

unread,
Feb 4, 2013, 12:07:57 PM2/4/13
to json-...@googlegroups.com

Yes, it does. :)

But my issue is not actually with whether "$ref" works (that's an F, btw, not an L).  The "$ref" is just a tool - the issue is that the fragment path specified with "$data" is an absolute position relative to the document root.

If someone wants to then include your format as part of their format (e.g. making a list of menu selections), then that absolute position in the document no longer makes sense.

frontend_dev

unread,
Feb 4, 2013, 12:25:02 PM2/4/13
to json-...@googlegroups.com

But the "given path" is a JSON Pointer path, which means that the data being verified must exist at a particular position relative to the document root for this schema to work.

Basically, yes. But in my eyes, the data must not even exist - if not it is simply undefined, just like if a specified property is simply missing from the data object. No big difference, right?
 
What if you define your format as above, but then I want to submit/validate a list of such instances, or I want to describe a map from restaurant visitors to their menu choices?  A JSON Pointer fragment would no longer point at the correct place.

Hmm also a more concrete Example would really help here!

Plus, of course you could also link to an object or array on your data and work from there, like this:

var data = {
      sub1: {
         sub2: "value"
     }
}


and then, in the schema:

"$data:#/sub1" : { "properties" : { "sub2" : { "enum" : "drinks" }}}

Geraint Luff

unread,
Feb 4, 2013, 12:32:40 PM2/4/13
to json-...@googlegroups.com
On 4 February 2013 17:25, frontend_dev <kude...@alphanull.de> wrote:

But the "given path" is a JSON Pointer path, which means that the data being verified must exist at a particular position relative to the document root for this schema to work.

Basically, yes. But in my eyes, the data must not even exist - if not it is simply undefined, just like if a specified property is simply missing from the data object. No big difference, right?
 
What if you define your format as above, but then I want to submit/validate a list of such instances, or I want to describe a map from restaurant visitors to their menu choices?  A JSON Pointer fragment would no longer point at the correct place.

Hmm also a more concrete Example would really help here!

OK - say you have your format.  Let's use the menu selection format from your examples.

{
    "type": "object",
    "properties": {
        "main": {"enum": ["food", "drink"]},
        "sub" : {
          "oneOf" : [
            {
               "$data:#/main" : { "enum" : ["food"] },
               "enum" : ["steak, "bread"]   
            },

            {
               "$data:#/main" : { "enum" : ["drinks"] },
               "enum" : ["water, "juice"]   
            }
         ]
      }
    }

}

Here's some example data:
{

    "main": "food",
    "sub": "steak"
}

That's great - the schema concisely describes the shape of the data.

But now I have a new challenge.  By referencing the existing schema, I want to describe the data below:
[
    {"main": "food", "sub": "steak"},

    {"main": "food", "sub": "bread"},
    {"main": "drink", "sub": "water"},
    {"main": "food", "sub": "steak"}
]


What I want to write is simply this:
{
    "type": "array",
    "items": {"$ref": "/path/to/other/schema"}
}

But the schema at "/path/to/other/schema" uses the "$data:" syntax - this means that the value of the "sub" property depends on the value at "#/main"...

... except "#/main" no longer exists.  What you actually need is "#/0/main", or "#/1/main", or....

Is that helpful at all?

Plus, of course you could also link to an object or array on your data and work from there, like this:

var data = {
      sub1: {
         sub2: "value"
     }
}


and then, in the schema:

"$data:#/sub1" : { "properties" : { "sub2" : { "enum" : "drinks" }}}

--

frontend_dev

unread,
Feb 4, 2013, 12:35:33 PM2/4/13
to json-...@googlegroups.com

But my issue is not actually with whether "$ref" works (that's an F, btw, not an L). 

Ups, excuse my sloppiness ... also please excuse for my typos.
 
The "$ref" is just a tool - the issue is that the fragment path specified with "$data" is an absolute position relative to the document root.

If someone wants to then include your format as part of their format (e.g. making a list of menu selections), then that absolute position in the document no longer makes sense.

Well, why? If they are using the same data, of course it should work. Well, and if they are using different data , they also need a different schema, right?

So I still don't see an issue ;)

frontend_dev

unread,
Feb 4, 2013, 12:38:43 PM2/4/13
to json-...@googlegroups.com

What I want to write is simply this:
{
    "type": "array",
    "items": {"$ref": "/path/to/other/schema"}
}

But the schema at "/path/to/other/schema" uses the "$data:" syntax - this means that the value of the "sub" property depends on the value at "#/main"...

... except "#/main" no longer exists.  What you actually need is "#/0/main", or "#/1/main", or....

Yes of course! Because "main" is now an array! But then it isn't simply the same data anymore? Of course, the schema / dependencies must be adapted then?

Still do not get this.

frontend_dev

unread,
Feb 4, 2013, 12:44:32 PM2/4/13
to json-...@googlegroups.com
And regarding  your example, what about this:

{
    "type": "object",
    "properties": {
        "main": {"enum": ["food", "drink"]},
        "sub" : {
          "oneOf" : [
            {
               "$data:../main" : { "enum" : ["food"] },
               "enum" : ["steak, "bread"]   
            },

            {
               "$data:../main" : { "enum" : ["drinks"] },
               "enum" : ["water, "juice"]   
            }
         ]
      }
    }

}

The relative link would indicate that the property has to be evaluated from your current scope, not beginning from document root. That - on a first glance at least - should also solve your array problem, right?

Francis Galiegue

unread,
Feb 4, 2013, 12:50:27 PM2/4/13
to json-...@googlegroups.com
On Mon, Feb 4, 2013 at 6:44 PM, frontend_dev <kude...@alphanull.de> wrote:
[...]
> "$data:../main" : { "enum" : ["drinks"] },
[...]
>
> The relative link would indicate that the property has to be evaluated from
> your current scope, not beginning from document root. That - on a first
> glance at least - should also solve your array problem, right?
>

I'm afraid this cannot work: ".." is a valid JSON object member name.
In fact, it can be any string, even the empty string.

frontend_dev

unread,
Feb 4, 2013, 12:58:01 PM2/4/13
to json-...@googlegroups.com

I'm afraid this cannot work: ".." is a valid JSON object member name.
In fact, it can be any string, even the empty string.

So JSON pointer cannot express any relative links? Hmmmm, that would smell also like a gap in the spec ;)

But I still stand by my point - even if you only could have absolute links. Then I would have in fact to change my schema with the example above, but since "main" is another type of data then, I wouldn't see this as a big problem.

Geraint Luff

unread,
Feb 4, 2013, 12:59:03 PM2/4/13
to json-...@googlegroups.com
Indeed it would.  I mean, there are issue to work out if you want to (for example) refer to a sibling property called ".." (the syntax being "../../")

But JSON Pointer has no relative links - so we'd be inventing our own variant of it, which gives me the screaming heeby-jeebies.

Geraint Luff

unread,
Feb 4, 2013, 1:07:03 PM2/4/13
to json-...@googlegroups.com
On 4 February 2013 17:59, Geraint Luff <gerai...@gmail.com> wrote:
On 4 February 2013 17:44, frontend_dev <kude...@alphanull.de> wrote:
And regarding  your example, what about this:

{
    "type": "object",
    "properties": {
        "main": {"enum": ["food", "drink"]},
        "sub" : {
          "oneOf" : [
            {
               "$data:../main" : { "enum" : ["food"] },
               "enum" : ["steak, "bread"]   
            },

            {
               "$data:../main" : { "enum" : ["drinks"] },
               "enum" : ["water, "juice"]   
            }
         ]
      }
    }

}

The relative link would indicate that the property has to be evaluated from your current scope, not beginning from document root. That - on a first glance at least - should also solve your array problem, right?

Indeed it would.  I mean, there are issue to work out if you want to (for example) refer to a sibling property called ".." (the syntax being "../../")

But JSON Pointer has no relative links - so we'd be inventing our own variant of it, which gives me the screaming heeby-jeebies.

Aside from that - I have to say I'm not a fan of the "$data:" syntax.  In a JSON document (such as a JSON Schema) all the structure of the information should be expressed using JSON structures.  You should prefer not to do semantic parsing of string values, and you should definitely not be doing semantic parsing of object keys.

We could design an alternative syntax, though.

Francis Galiegue

unread,
Feb 4, 2013, 1:11:03 PM2/4/13
to json-...@googlegroups.com
On Mon, Feb 4, 2013 at 6:58 PM, frontend_dev <kude...@alphanull.de> wrote:
>
>> I'm afraid this cannot work: ".." is a valid JSON object member name.
>> In fact, it can be any string, even the empty string.
>
>
> So JSON pointer cannot express any relative links? Hmmmm, that would smell
> also like a gap in the spec ;)
>

Well, its goal is to address _without error_ any JSON value you can
think of, existing, past or future. And it is the only specification
able to achieve that...

frontend_dev

unread,
Feb 4, 2013, 1:20:18 PM2/4/13
to json-...@googlegroups.com
Indeed it would.  I mean, there are issue to work out if you want to (for example) refer to a sibling property called ".." (the syntax being "../../")

Well, on the other hand, who on earth will name his JSON property ".." ?

It really wouldn't make no sense for me, hell you could even not access this property using standard "dot notation" anymore when you parse this into javascript - and you WILL have to parse it in javascript to actually work with it.

think of value = data... -> Syntax Error

only this one would work then: value = data[".."]

 
But JSON Pointer has no relative links - so we'd be inventing our own variant of it, which gives me the screaming heeby-jeebies.

Well, if someone uses ".." as a data attribute name, then _I_ would have screaming heeby-jeebies then ;)

But anyway, of course I think relative links should follow standard conventions also in JSON Pointers. That is: "../"

How about solving the problem? 2 thoughts:

a) simply disallow ".." as property name.
b) allow it. In this case, check if a property named ".." actually exists on the data, and if yes, treat ".." as a normal property and continue resolving from there.

Francis Galiegue

unread,
Feb 4, 2013, 1:21:25 PM2/4/13
to json-...@googlegroups.com
On Mon, Feb 4, 2013 at 7:20 PM, frontend_dev <kude...@alphanull.de> wrote:
>> Indeed it would. I mean, there are issue to work out if you want to (for
>> example) refer to a sibling property called ".." (the syntax being "../../")
>
>
> Well, on the other hand, who on earth will name his JSON property ".." ?
>

This is perfectly reasonable if you use JSON to describe relative
filesystem entries.

The core of the fact is, it is possible and must be accounted for.

Francis Galiegue

unread,
Feb 4, 2013, 1:23:55 PM2/4/13
to json-...@googlegroups.com
On Mon, Feb 4, 2013 at 7:21 PM, Francis Galiegue <fgal...@gmail.com> wrote:
[...]
>
> This is perfectly reasonable if you use JSON to describe relative
> filesystem entries.
>

Heh, ".." is part of every output of "ls -a", for that matter. If you
use JSON to present the results of this command, you'll have to deal
with that every single time ;)

Still reluctant to having a dedicated DSL?

frontend_dev

unread,
Feb 4, 2013, 1:26:47 PM2/4/13
to json-...@googlegroups.com
Aside from that - I have to say I'm not a fan of the "$data:" syntax.  In a JSON document (such as a JSON Schema) all the structure of the information should be expressed using JSON structures.  You should prefer not to do semantic parsing of string values, and you should definitely not be doing semantic parsing of object keys.

Yes, in a way I agree to that. I mainly choose this to better illustrate what I mean.
 
We could design an alternative syntax, though.

Sure! How could it look like?

say, when you define it like this:

"$data" : "URI"

how do you "connect" it to a schema? My "demo" syntax at least had the advantage of clearly expressing that.

frontend_dev

unread,
Feb 4, 2013, 1:28:49 PM2/4/13
to json-...@googlegroups.com

This is perfectly reasonable if you use JSON to describe relative
filesystem entries.

The core of the fact is, it is possible and must be accounted for.

OK, then:


b) allow it. In this case, check if a property named ".." actually exists on the data, and if yes, treat ".." as a normal property and continue resolving from there.

or just only allow absolute paths like before, be it from document root or an URI?

Geraint Luff

unread,
Feb 4, 2013, 1:38:02 PM2/4/13
to json-...@googlegroups.com
On 4 February 2013 18:26, frontend_dev <k...@alphanull.de> wrote:
Aside from that - I have to say I'm not a fan of the "$data:" syntax.  In a JSON document (such as a JSON Schema) all the structure of the information should be expressed using JSON structures.  You should prefer not to do semantic parsing of string values, and you should definitely not be doing semantic parsing of object keys.

Yes, in a way I agree to that. I mainly choose this to better illustrate what I mean.
 
We could design an alternative syntax, though.

Sure! How could it look like?

say, when you define it like this:

"$data" : "URI"

how do you "connect" it to a schema? My "demo" syntax at least had the advantage of clearly expressing that.

It was very clear to read - I just didn't like the fact that it required string parsing of an object key.

Any alternative would have to be more verbose, like:
{
    "$path": "/blah",
    "schema": {...}

Geraint Luff

unread,
Feb 4, 2013, 1:38:42 PM2/4/13
to json-...@googlegroups.com
On 4 February 2013 18:23, Francis Galiegue <fgal...@gmail.com> wrote:
On Mon, Feb 4, 2013 at 7:21 PM, Francis Galiegue <fgal...@gmail.com> wrote:
[...]
>
> This is perfectly reasonable if you use JSON to describe relative
> filesystem entries.
>

Heh, ".." is part of every output of "ls -a", for that matter. If you
use JSON to present the results of this command, you'll have to deal
with that every single time ;)

Still reluctant to having a dedicated DSL?

It is getting a little convoluted... :p


--
Francis Galiegue, fgal...@gmail.com
Try out your JSON Schemas: http://json-schema-validator.herokuapp.com

frontend_dev

unread,
Feb 4, 2013, 5:06:45 PM2/4/13
to json-...@googlegroups.com

Still reluctant to having a dedicated DSL?

yes ;)
 
It is getting a little convoluted... :p

well, forget about what I said about relative JSON pointers ;)

 ... that seems like another topic.

Francis Galiegue

unread,
Feb 4, 2013, 5:16:23 PM2/4/13
to json-...@googlegroups.com
On Mon, Feb 4, 2013 at 11:06 PM, frontend_dev <kude...@alphanull.de> wrote:
>
>>> Still reluctant to having a dedicated DSL?
>
>
> yes ;)
>

Ah, too bad. I am sure it could provide a nice, human readable way of
building forms... Say:

[
{ "select": "country" },
{ "select": "type" }
]

(always for beers), and then the rest of the form could be built automatically.

Just one thing: I have not followed all of the discussion, but have
you considered the "default" keyword?

frontend_dev

unread,
Feb 4, 2013, 5:26:28 PM2/4/13
to json-...@googlegroups.com

> yes ;)
>

Ah, too bad. I am sure it could provide a nice, human readable way of
building forms... Say:

[
    { "select": "country" },
    { "select": "type" }
]

The problem I have with this that it explicitly says that I should present the data as a <select>.

But: is this always appropriate? Especially for enums, there are several possibilities: a select, a set of radiobuttons etc.

I would leave this decision to the view / renderer since I also have to build mobile _and_ desktop layouts, I am sure my forms will differ a bit.


Just one thing: I have not followed all of the discussion, but have
you considered the "default" keyword?

Considered for what?

frontend_dev

unread,
Feb 4, 2013, 5:32:33 PM2/4/13
to json-...@googlegroups.com

[
    { "select": "country" },
    { "select": "type" }
]

And it wouldn't solve the problem of "convoluted branches starting from root"

frontend_dev

unread,
Feb 4, 2013, 5:54:09 PM2/4/13
to json-...@googlegroups.com
Any alternative would have to be more verbose, like:
{
    "$path": "/blah",
    "schema": {...}
}

yes, that would be one possibilty, or you could embed the data path directly in the schema, like this:

{
   "scope" : "/bla"
   ... rest of schema definition
}


I can imagine that both ways could do it.

Austin Wright

unread,
Feb 4, 2013, 8:21:00 PM2/4/13
to json-...@googlegroups.com
It looks like if you really want to do this, you could use a more advanced JSON Schema library that allows you to define your own properties and callbacks for handling instances. Then you define a property "data" that calls a callback, and asks the application "Get me the data that you meant by /x/y/z" and validates that instance against a schema defined by another property ("dataschema"?), and so it sort of dodges the question entirely of "What is $data relative to?"

On Sunday, February 3, 2013 9:15:02 AM UTC-7, frontend_dev wrote:

So you'd like a vocabulary which can do something like this: A schema is a set of instructions that must all validate to return valid. Introduce an instruction that validates some other instance elsewhere against a given schema.

Basically, yes. Instead of "elsewhere" one could say: "that validates ANY instance against a given schema" (not only restricted to properties of the current  scope)
 
I can't imagine this being necessary in JSON Schema. I believe one can prove that for every possible way you could use this instruction, you can also build a schema that works with existing instructions (properties).

Ok, so given only the existing solution, how do you:

- express a dependency that does not need to "start from root" if you want to compare to a sibling property
- create a schema that can be easily analyzed by a human _or_ piece of code, for example in order to evaluate what concrete schema one given property has
- create a schema where it can be easily evaluated what dependencies actually apply

and:

- create a schema that allows to validate a given instance against a value from another instance. For example you need to validate a piece of data against some data that resides on a remote URI. Not possible right now imho.
 

I mean, I can't see any reason to be against this exactly, and there's nothing wrong with introducing features that simplify a schema document, but be aware it would require a radical re-design of how schemas are currently understood, processed, and written, given their current status as being context-free.

I also don't think that the redesign would be "radical". It is imho not even a redesign, since nothing that already exists has to be changed or would break, not need for rewriting anything, since the way of expressing dependencies is still "anyOf", "oneOf" etc. Even the way a validating algorithm works is absolutely the same, there is in fact only _one_ difference I see when it comes to accessing the actual values we validate aginst:

Instead of evaluating the concrete data value based on the property structure of the schema (and therefore essentially limiting branches to "sub-properties"  only) the validator just has to get the value from a specified path or let's better say: URI (absolute or relative) and "feed" the schema with the result derived from there instead. The actual validation should not change, just the value/object it is compared against.
 
Of course, I might miss something, but I still do not see anything ;) In fact it _seems_ so easy, that I'd like to simply try it out.

Geraint Luff

unread,
Feb 5, 2013, 5:01:41 AM2/5/13
to json-...@googlegroups.com
On 4 February 2013 22:26, frontend_dev <kude...@alphanull.de> wrote:

> yes ;)
>

Ah, too bad. I am sure it could provide a nice, human readable way of
building forms... Say:

[
    { "select": "country" },
    { "select": "type" }
]

The problem I have with this that it explicitly says that I should present the data as a <select>.

But: is this always appropriate? Especially for enums, there are several possibilities: a select, a set of radiobuttons etc.

I would leave this decision to the view / renderer since I also have to build mobile _and_ desktop layouts, I am sure my forms will differ a bit.
 
How about a keyword like "role"?

It could have other uses - for example, a role of "switch" would indicate that that property should be used to switch betwen schema options.  A role of "title" and "text" would be useful for any search engines that were walking/indexing JSON content (completely possible if you document your API with hyper-schema), and a role of "meta" or "binary" would indicate that it's not human-viewable.

Just one thing: I have not followed all of the discussion, but have
you considered the "default" keyword?

Considered for what?

I'm afraid I don't see it either - it's informative when doing value creation, but I don't quite see how it would help with this switching problem...
 

frontend_dev

unread,
Feb 5, 2013, 9:37:22 AM2/5/13
to json-...@googlegroups.com

It looks like if you really want to do this, you could use a more advanced JSON Schema library that allows you to define your own properties and callbacks for handling instances.

And such a library exists? Which also supports v04?
 
Then you define a property "data" that calls a callback, and asks the application "Get me the data that you meant by /x/y/z" and validates that instance against a schema defined by another property ("dataschema"?), and so it sort of dodges the question entirely of "What is $data relative to?"

Well, then in this case I would not only have to write a renderer, but also a validator, and on top of that my own schema format, which would be almost identical to a JSON Schema anyway. And I could not use any standard tools like the online validator anymore.

Seems like a very hard and lonely road I would walk upon then.

And I still think that data referencing would be a very useful addition to the JSON schema, and if it only is a more clearly and easily readable structure.

But, well ... I might have been wrong : /

Francis Galiegue

unread,
Feb 5, 2013, 9:38:47 AM2/5/13
to json-...@googlegroups.com
On Tue, Feb 5, 2013 at 3:37 PM, frontend_dev <kude...@alphanull.de> wrote:
>
>> It looks like if you really want to do this, you could use a more advanced
>> JSON Schema library that allows you to define your own properties and
>> callbacks for handling instances.
>
>
> And such a library exists? Which also supports v04?
>

In Java, yes: mine.

frontend_dev

unread,
Feb 5, 2013, 9:44:24 AM2/5/13
to json-...@googlegroups.com

How about a keyword like "role"?

It could have other uses - for example, a role of "switch" would indicate that that property should be used to switch betwen schema options.  A role of "title" and "text" would be useful for any search engines that were walking/indexing JSON content (completely possible if you document your API with hyper-schema), and a role of "meta" or "binary" would indicate that it's not human-viewable.

That sounds interesting, but it also does not solve the problem with the "oneOf" structure.

I also think it would be interesting to extend the schema so that it is more useful for presenting (which it already is), but i think this should be done on an abstract way. Not clear how "role" fits in there.

Another thing would be to be able to group data, eg indicate what fields belong together in a semantical way. But again, I would never "hardcode" this with a tag like "fieldset", bc one client might decide to not group the form into fieldsets, but rather in separated tabs (eg mobile view)

You could even argue that in fact this is also a kind of more abstract data desciption - that also can be used for presenting - and no explicit statement how to exactly present that given field. Thats the one thing I would try to avoid with such an extension.

But still, I think to be able to reference data should belong to the core specification, since that isn't presentation specific at all.

frontend_dev

unread,
Feb 5, 2013, 9:45:33 AM2/5/13
to json-...@googlegroups.com
In Java, yes: mine.

Unfortunately, I am tied to Javascript, since I am a frontend_dev ;)

Francis Galiegue

unread,
Feb 5, 2013, 9:49:25 AM2/5/13
to json-...@googlegroups.com
On Tue, Feb 5, 2013 at 3:45 PM, frontend_dev <kude...@alphanull.de> wrote:
>> In Java, yes: mine.
>
> Unfortunately, I am tied to Javascript, since I am a frontend_dev ;)
>

Well, you know, AJAX exists ;)

This is how my online validator works. The only Javascript I use is
for presentation purposes... And when I experiment with form
generation, I'll do exactly the same.

Servers are here to work after all :p

frontend_dev

unread,
Feb 5, 2013, 9:50:02 AM2/5/13
to json-...@googlegroups.com


Just one thing: I have not followed all of the discussion, but have
you considered the "default" keyword?

Considered for what?

I'm afraid I don't see it either - it's informative when doing value creation, but I don't quite see how it would help with this switching problem...

it could be useful for setting up default values and therefore a "default dependency" if the user hasn't entered anything before.  But that of course also does not adress the  problem.

frontend_dev

unread,
Feb 5, 2013, 10:05:48 AM2/5/13
to json-...@googlegroups.com

Well, you know, AJAX exists ;)

Yes, of course, and will use AJAX almost exclusively, since my frontend I am working on has a very abstract REST style API that not only could be used by clients like a browser, but by a remote server as well. So, the server acts more like a web service, the whole communication is "data only" (ie JSON), there is not a single ounce of HTML transmitted (except for an almost "empty" starting page)

Therefore - since I have to load the schema anyway in the client - it simply makes no sense to introduce additional roundtrips to the server for each validation, when I also could validate directly in the client - that is the whole point of our concept, to free the server as much as we can by offloading work to the client. If I'd like to validate on a field basis or even while typing, this would unnecessarily slow down my UI.

Also, think of working offline ....

 
This is how my online validator works. The only Javascript I use is
for presentation purposes... And when I experiment with form
generation, I'll do exactly the same.

Servers are here to work after all :p

Yes, but we have a more "dumb" backend here, that does not (and should not!) know much about the client.

Plus: my backend guy is very reluctant to install ANY software on the server that is not absolutely not needed. And I don't think it makes sense to support Java only  for something that should be solved another way in our case.
It is loading more messages.
0 new messages