Skip to content

Commit

Permalink
Fixed resolve_uri example
Browse files Browse the repository at this point in the history
  • Loading branch information
danielaparker committed Dec 28, 2024
1 parent d0a74ce commit dde0554
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 50 deletions.
74 changes: 40 additions & 34 deletions doc/ref/jsonschema/jsonschema.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,24 @@ Output:

<div id="eg3"/>

#### 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
{
Expand All @@ -376,45 +390,36 @@ second schema defined in an external file, `name-defs.json`,
}
```

```cpp
#include <jsoncons/json.hpp>
#include <jsoncons_ext/jsonschema/jsonschema.hpp>
#include <fstream>
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
Expand Down Expand Up @@ -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
Expand Down
34 changes: 18 additions & 16 deletions examples/src/jsonschema_examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand All @@ -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
Expand Down Expand Up @@ -192,7 +194,7 @@ void defaults_example()
json data = json::parse("{}");

// will throw schema_error if JSON Schema compilation fails
jsonschema::json_schema<json> compiled = jsonschema::make_json_schema(schema, resolve);
jsonschema::json_schema<json> compiled = jsonschema::make_json_schema(schema);

// will throw a validation_error when a schema violation happens
json patch;
Expand Down

0 comments on commit dde0554

Please sign in to comment.