diff --git a/doc/ref/jsonschema/jsonschema.md b/doc/ref/jsonschema/jsonschema.md index 92074a487..ef03ff6cc 100644 --- a/doc/ref/jsonschema/jsonschema.md +++ b/doc/ref/jsonschema/jsonschema.md @@ -351,10 +351,24 @@ Output:
-#### Resolving references to schemas defined in external files +#### Resolving references to schemas defined in external files -In this example, the main schema defines a reference using the `$ref` property to a -second schema defined in an external file, `name-defs.json`, +In this example, the main schema is + +```json +{ + "$id" : "https://www.example.com", + "$schema": "https://json-schema.org/draft/2020-12/main_schema", + "$id": "http://localhost:1234/draft2020-12/object", + "type": "object", + "properties": { + "name": {"$ref": "/name-defs.json#/$defs/orNull"} + } +} +``` + +The main schema defines a reference using the `$ref` keyword to a +second schema defined in an external file, `name-defs.json`, ```json { @@ -376,45 +390,36 @@ second schema defined in an external file, `name-defs.json`, } ``` -```cpp -#include -#include -#include +jsoncons allows you to write a resolve function object to handle the URI +of the external file and translate it into a physical pathname. -// for brevity -using jsoncons::json; -namespace jsonschema = jsoncons::jsonschema; +```cpp +auto resolve = [](const jsoncons::uri& uri) -> json + { + std::cout << "Requested URI: " << uri.string() << "\n"; + std::cout << "base: " << uri.base().string() << ", path: " << uri.path() << "\n\n"; -json resolve(const jsoncons::uri& uri) -{ - std::cout << "base: " << uri.base().string() << ", path: " << uri.path() << "\n\n"; + std::string pathname = "./input/jsonschema"; + pathname += std::string(uri.path()); - std::string pathname = "./input/jsonschema"; - pathname += std::string(uri.path()); + std::fstream is(pathname.c_str()); + if (!is) + { + return json::null(); + } - std::fstream is(pathname.c_str()); - if (!is) - { - return json::null(); - } + return json::parse(is); + }; +``` - return json::parse(is); -} +When building the main schema, the schema builder needs to resolve the URI 'https://www.example.com/name-defs.json#/$defs/orNull'. +The user does not need to supply that specific subschema, it is enough to supply the schema document '/name-defs.json'. +The schema builder than processes that schema document and makes multiple entries into an internal validator registry, +including an entry for 'https://www.example.com/name-defs.json#/$defs/orNull'. +```cpp int main() { - std::string main_schema = R"( -{ - "$id" : "https://www.example.com", - "$schema": "https://json-schema.org/draft/2020-12/main_schema", - "$id": "http://localhost:1234/draft2020-12/object", - "type": "object", - "properties": { - "name": {"$ref": "/name-defs.json#/$defs/orNull"} - } -} - )"; - json schema = json::parse(main_schema); // Data @@ -452,6 +457,7 @@ int main() ``` Output: ``` +Requested URI: https://www.example.com/name-defs.json#/$defs/orNull base: https://www.example.com/name-defs.json, path: /name-defs.json /name: Must be valid against at least one schema, but found no matching schemas diff --git a/examples/src/jsonschema_examples.cpp b/examples/src/jsonschema_examples.cpp index b3c33e6ff..02233a712 100644 --- a/examples/src/jsonschema_examples.cpp +++ b/examples/src/jsonschema_examples.cpp @@ -106,21 +106,6 @@ void validate_three_ways() } // Until 0.174.0, throw a `schema_error` instead of returning json::null() -json resolve(const jsoncons::uri& uri) -{ - std::cout << "base: " << uri.base().string() << ", path: " << uri.path() << "\n\n"; - - std::string pathname = "./input/jsonschema"; - pathname += std::string(uri.path()); - - std::fstream is(pathname.c_str()); - if (!is) - { - return json::null(); - } - - return json::parse(is); -} void resolve_uri_example() { @@ -136,6 +121,23 @@ void resolve_uri_example() } )"; + auto resolve = [](const jsoncons::uri& uri) -> json + { + std::cout << "Requested URI: " << uri.string() << "\n"; + std::cout << "base: " << uri.base().string() << ", path: " << uri.path() << "\n\n"; + + std::string pathname = "./input/jsonschema"; + pathname += std::string(uri.path()); + + std::fstream is(pathname.c_str()); + if (!is) + { + return json::null(); + } + + return json::parse(is); + }; + json schema = json::parse(main_schema); // Data @@ -192,7 +194,7 @@ void defaults_example() json data = json::parse("{}"); // will throw schema_error if JSON Schema compilation fails - jsonschema::json_schema compiled = jsonschema::make_json_schema(schema, resolve); + jsonschema::json_schema compiled = jsonschema::make_json_schema(schema); // will throw a validation_error when a schema violation happens json patch;