Validation
What makes a document valid: the schemas, and the rules they cannot state, each with the code of its finding.
The rules can still change before the first release.
A document is valid when it passes two layers of checks. The schemas state
the first layer. This page states the second, which JSON Schema cannot
express. The validator in @opencycle/ods-schema runs both.
Each failed check is reported as a Finding with level
error, origin check, the code below, a message that names the field,
and the field's place in the document as a JSON Pointer (RFC 6901) in
data.path.
1. Layer one: the schemas
The document is valid against core/Document.json under JSON Schema
2020-12, with the date-time and uri formats checked. A failure has the
code schema.
2. Layer two: the rules
| Code | Rule |
|---|---|
id.duplicate |
Each record's id is unique within the document. |
reference.unresolved |
A field with x-ods-ref holds the id of a record in the document. |
reference.type |
When x-ods-ref names a schema, that record is of that schema. With x-ods-ref: "*", a record of any schema passes. A Link with a targetType that is a schema's name points at a record of that schema. |
code.unknown |
A field with x-ods-vocabulary holds a code of that vocabulary. For */<name>, a code of that vocabulary in any module passes. The coordinates of an Axis with a vocabulary are codes of it. |
unit.mismatch |
A Value for a quantity has the unit of the quantity's term, and no unit when the term has none. This applies to a Property's value and range (for its type), an Emission's value (for its type), an Evidence's result (for its observed), an Axis's unit (for its quantity), and a trace step's input or output that names a quantity: its value and the value of its fallback. |
value.type |
Each element of such a Value's amount is of the term's valueType. null marks no data and passes. |
value.range |
Each number in such a Value's amount lies within the term's minimum and maximum. A Value whose statistic is standard_deviation, standard_error or count is not checked: it does not lie on the quantity's scale. |
value.not_allowed |
When the term lists values, each text element of the amount is one of them. |
axes.shape |
The amount of a Value with axes is a list that nests one level per axis, and its length at each level equals the number of coordinates of that axis (the length of values, or count). null in place of an element or of a nested list marks no data and passes. The edges of an axis's bins number one more than its coordinates. A list uncertainty.amount has the same shape as the amount. |
axes.crs |
A Value with an axis whose quantity is easting, northing, longitude or latitude has a crs. |
axes.record |
The coordinates of an Axis whose quantity is record are ids of records in the document. |
crs.conflict |
A Crs with an epsgCode and a code whose authority is EPSG names one system: the code is EPSG: and the epsgCode. A code of another authority is not compared. |
linear.line |
The record that a LinearReference's line points at has a geometry that is a LineString or a MultiLineString. |
verdict.level |
A verdict's level is the worst level of its subjects that have one: fail when one fails, else partial when one is met only in part, else pass. A subject with no level was not judged and does not count. A verdict with no judged subject is not compared. |
comparison.verdict |
A Comparison's verdict follows from its difference and tolerance. A pass or a fail has a tolerance, and does not have judged of 0. When the difference's and the tolerance's amounts are numbers in the same unit (or both have none), the verdict is pass when the size of the difference is at most the tolerance, else fail. Amounts in two units are not compared. |
A Value whose amount sits in a file is checked for its unit, its axes'
bins and its crs, not for its elements: the validator does not read
files.
3. What is not checked
- The contents of files, and their hashes: the package verifier checks those (package format).
- A Criterion's
limitand other Expressions: their Values have no quantity beside them. The profile check reads the expressions of a regulator profile (regulator profiles). - Whether a trace follows from its flow: the trace check does that (regulator profiles).
- A Crs's
wktandprojjson, and whether acodeexists in its registry: the validator does not read a definition or a registry (places and shapes). - Whether coordinates lie inside the area of their coordinate reference system, or agree with a geographic identifier or a linear reference.
x-extension keys: a reader may ignore them.