nox-jsonschema #
JSON Schema draft-07 validation for nox-json values.
Every keyword of the draft-07 validation vocabulary is checked. $ref
resolves within the schema and across the documents handed in by URI, never
over the network. The draft-07 metaschema is bundled, and every schema is
checked against it before use. Each error names the failing value and the
failing keyword by JSON Pointer (RFC 6901).
Usage #
let schema =
Json.Value.of_string_exn
{|{"type": "object",
"properties": {"tags": {"type": "array", "items": {"type": "string"}}}}|}
let t = Result.get_ok (Jsonschema.v schema)
let () =
match Jsonschema.validate t (Json.Value.of_string_exn {|{"tags": ["a", 2]}|}) with
| Error [ e ] ->
assert (Jsonschema.instance e = "/tags/1");
assert (
Jsonschema.keyword e = "urn:nox-jsonschema:root#/properties/tags/items/type")
| _ -> assert false
Jsonschema.pp_error prints that error as
/tags/1: integer is not of type string (urn:nox-jsonschema:root#/properties/tags/items/type)
A schema that references another document by URI receives it through
~resources, keyed by the absolute URI the reference resolves to:
let licence = Json.Value.of_string_exn {|{"enum": ["MIT", "ISC"]}|}
let t =
Result.get_ok
(Jsonschema.v
~resources:[ ("http://example.com/licence.json", licence) ]
(Json.Value.of_string_exn
{|{"$id": "http://example.com/root.json",
"allOf": [{"$ref": "licence.json"}]}|}))
let () = assert (not (Jsonschema.is_valid t (Json.Value.string "GPL")))
Conformance #
The test suite replays the draft-7 files of the official
JSON-Schema-Test-Suite
verbatim, at a pinned commit (test/interop/json-schema-test-suite), with
every required file and the optional format files for each format asserted.
The optional files it does not run are named in test/interop/json-schema-test-suite/test.ml with
the reason for each: ECMA-262 regular expressions beyond what Re.Perl
compiles, idn-hostname and uri-template, which section 7.2 lets an
implementation leave unchecked, and contentMediaType and
contentEncoding, which section 8 makes annotations.
Related work #
- jsonschema (opam
jsonschema, hence this package'snox-name) validates drafts 4 to 2020-12 over Yojson values. Nothing in this tree uses Yojson, and adopting it would put a second JSON representation,ppx_deriving_yojsonand a conversion of every document into the closure of every consumer. - ocplib-json-typed and its successor json-data-encoding describe JSON Schema documents but do not validate instances against them.
- Python's jsonschema is
the reference the CycloneDX tooling uses; its
check-jsonschemacommand is the oracle ofocaml-sbom's committed validation trace.