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!
The problem here is with your schema. First you tell it to reference
to one definition _but then_ you constrain it with an enum:
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.
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.
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.
--
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.
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".
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.
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.
If your schema were written so as to _force_ GUIs one way or another, you lose.
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?
On Thu, Jan 31, 2013 at 6:30 PM, Francis Galiegue <fgal...@gmail.com> wrote:
[...]
>And there is something else as well: say you have a schema for a
> 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.
>
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.
--
Francis Galiegue, fgal...@gmail.com
Try out your JSON Schemas: http://json-schema-validator.herokuapp.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:
{"oneOf": [
"type": "object",
"properties" : {
"main" : { "enum" : ["drinks","food"] },
"sub" : {
{
"#/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.
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.
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?
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.
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.
Did you check the "editable" checkbox? Otherwise it simply annotates the data with schema titles.
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?
What are the other non-UI benefits of it, though? What can you say with it that you can't already say?
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. :)
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.
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.
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.
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?
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.
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.
But in terms of the set of possible values that it allows, that set of constraints is completely equivalent to the following:
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.
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.
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 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?
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?
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.
OK, first off - I'm sorry it took me so long to understand what you were saying.
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.
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.
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.
However, I am extremely reluctant to sacrifice "context-free" validation, so I would be interested in looking at solutions that sustain that property.
There are already URI scopes defined by "id". And those are complex enough :p
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.
I wonder if adding another constraint to the schema would do it.
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.
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.
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!
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.
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.
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".
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.
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.
On Saturday, February 2, 2013 7:37:10 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.
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.
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.
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.
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 agree - it would change some quite fundamental properties, and we shouldn't do it lightly.
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.
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.
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...
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".
To unsubscribe from this group and stop receiving emails from it, send an email to j...@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.
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).
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
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.
--
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.
--
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.
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?
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.
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" }}}
--
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.
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....
I'm afraid this cannot work: ".." is a valid JSON object member name.
In fact, it can be any string, even the empty string.
On 4 February 2013 17:44, frontend_dev <kude...@alphanull.de> wrote:And regarding your example, what about this:"$data:../main" : { "enum" : ["food"] },"sub" : {
{
"type": "object",
"properties": {
"main": {"enum": ["food", "drink"]},
"oneOf" : [
{
"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.
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.
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.
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.
> This is perfectly reasonable if you use JSON to describe relativeHeh, ".." is part of every output of "ls -a", for that matter. If you
> filesystem entries.
>
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?
--
Francis Galiegue, fgal...@gmail.com
Try out your JSON Schemas: http://json-schema-validator.herokuapp.com
Still reluctant to having a dedicated DSL?
It is getting a little convoluted... :p
> yes ;)
>
Ah, too bad. I am sure it could provide a nice, human readable way of
building forms... Say:
[
{ "select": "country" },
{ "select": "type" }
]
Just one thing: I have not followed all of the discussion, but have
you considered the "default" keyword?
[
{ "select": "country" },
{ "select": "type" }
]
Any alternative would have to be more verbose, like:{"$path": "/blah","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.
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.
> 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?
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?"
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.
In Java, yes: mine.
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...
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