java-json-tools / json-schema-validator

A JSON Schema validation implementation in pure Java, which aims for correctness and performance, in that order
http://json-schema-validator.herokuapp.com/
Other
1.63k stars 399 forks source link

Is there a way to print a schema with references resolved? #41

Closed kelvinpho closed 11 years ago

kelvinpho commented 11 years ago

Hi,

I'm not having any issues with SchemaNode and validation, but I would like a way to print my SchemaNode with $ref resolved. An example of this is on http://www.jsonschema.net/ where they can pretty print the Json Schema in JSON format.

Is there any way to do this with json-schema-validator's SchemaNode or SchemaTree?

Thanks!

fge commented 11 years ago

(what do you call SchemaNode? It was there in 1.x but does not exist in 2.x anymore) I am not sure here, do you want to actually extend BaseSchemaTree to include arbitrary metadata?

From your latter point, if I understand you correctly, you need to be able to tell apart what (un)marshalling process(or) will be used according to a defined field in the JSON representation of the data? I understood at first that you wanted to have two different schemas at the same URI. This is not the same thing ;)

This problem has already been expressed by @dportabella in another issue, and @joelittlejohn has also weighed in, since his project has the ability to generate a JSON Schema out of a POJO. But at a first step, have you looked at ProcessorSelector? It is part of the answer here since you can select what processor is to be called next according to an arbitrary predicate. See this link and search for the ProcessorSelector section:

https://github.com/fge/json-schema-core/wiki/Architecture

Or, if you can extract it more simply, use a ProcessorMap (this is what I do to determine what validation process should take place according to the detected schema version -- see SchemaValidator or ValidationProcessor).

What you would need is a predicate on the data here, so that the correct processing be selected afterwards. Which means processor join is not really relevant to your case, is it?

kelvinpho commented 11 years ago

I shouldn't need to extend any SchemaTree. I believe I can leverage defined JSON Schema features to get what I need here.

I think we are on the same page. Different "versions" of my messages will be at different URI's.

Oh, I have not read up on ProcessorMap yet. Let me dig into this a bit and I'll get back to you to see if this works. I probably won't be able to work through an example until Monday though.

fge commented 11 years ago

I guess I need to know what you call "defined JSON Schema features" here -- none exist that can tell one "serialized" type from another one, unless you choose to interpret an existing keyword in your own way. But then remember that you can add your own keywords. Can you explain more?

fge commented 11 years ago

OK, I have a working, tested implementation of Schemawalker -- one which resolves references, the other one which doesn't. I just need to make a processor out of it, document everything, and it'll be done.

As to the ref expander itself, I think I'll put it in json-schema-processor-examples, you will be able to pick it up from there.

fge commented 11 years ago

-core has been released with SchemaWalker in it. There are two of them: the first does not try to resolve JSON References while the second does. There is an associated Processor as well ;)

I'll illustrate how it works in json-schema-processor-examples, starting with a ref expander which will return a schema with all JSON References resolved. But that is not really needed anymore now ;)

fge commented 11 years ago

OK, -core 1.0.2, and -validator 2.0.1 have been released. Note: syntax validation and ref resolving have moved into -core. All the schema walking tree is into core.

As to ref expanding, there is an example here:

https://github.com/fge/json-schema-processor-examples/tree/master/src/main/java/com/github/fge/refexpand

However, since there is a ResolvingSchemaWalker which does ref expansion for you, maybe you don't need it anymore...

kelvinpho commented 11 years ago

Thanks for the updates! I got held up on some other tasks today, but I will work this in and let you know how it goes soon.

kelvinpho commented 11 years ago

So far so good on using the ResolvingSchemaWalker! I also noticed that the json schema throws warnings on unsupported keys. Warnings are perfect since it doesn't prevent the schema from being validated, and I can use unsupported keys as ways to mark-up the schema for my marshalling/unmarshalling logic.

I will mark this as closed for now and I will create another thread if I have any questions regarding the walkers.

Thanks very much for your help!

olgabo commented 7 years ago

I can't see RefExpander anymore in the master tree? Has it been removed?

queenaqian commented 5 years ago

I have the same requirement, is it a release feature to print a complete schema?

simmosn commented 5 years ago

I have the same requirement, is it a release feature to print a complete schema?

Have the same question also, did you get an answer on this?

huggsboson commented 5 years ago

I think where they landed, after reading the discussion is that you need to implement your own as a Schema walker. I didn't see them merge anything into the tree to do it. Happy to take a default implementation of it if any of you do it.

neerajsu commented 4 years ago

@olgabo , @queenaqian , @simmosn , @huggsboson

@fge actually provided ResolvingSchemaWalker which does everything what the OP needs out of the box. It took me to while to understand by looking at the source code, but it is very straightforward. Here's the code snippet for you to use.

URL url = classLoader.getResource("/some/schema/file/path/in/resource");
        JsonNode jsonNode = JsonLoader.fromURL(url);
        SchemaTree schemaTree = new CanonicalSchemaTree(jsonNode);
        ResolvingSchemaWalker resolvingSchemaWalker = new ResolvingSchemaWalker(schemaTree);
        SchemaExpander schemaTreeSchemaListener = new SchemaExpander(schemaTree);
        resolvingSchemaWalker.walk(schemaTreeSchemaListener, new ConsoleProcessingReport());
        SchemaTree resolvedSchemaTree = schemaTreeSchemaListener.getValue();

resolvedSchemaTree should now have all "$ref" in your schema resolved. Hope that answers your question.

danham-slalom commented 3 years ago

@neerajsu is the ResolvingSchemaWalker still available? I'm not able to find it in the repository. Any idea if it has been removed with more recent version changes? The latest version I can find mention of the ResolvingSchemaWalker is 1.1.8 but the latest version still available on maven central is 1.5.

neerajsu commented 3 years ago

@neerajsu is the ResolvingSchemaWalker still available? I'm not able to find it in the repository. Any idea if it has been removed with more recent version changes? The latest version I can find mention of the ResolvingSchemaWalker is 1.1.8 but the latest version still available on maven central is 1.5.

My comment is almost 2 years old. At that time, ResolvingSchemaWalker was experimental. So it's probably renamed and/or incorporated into main code. You'll have to dig into the latest source code to figure out. Im sure the functionality exists in the latest code.