Skip to content

Commit eed89de

Browse files
committed
Validate ontology file
1 parent b2410b9 commit eed89de

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

bin/validator.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
# dependencies = [
44
# "jsonschema>=4.26.0",
55
# "pyld>=2.0.4",
6+
# "rdflib>=7.0.0",
67
# ]
78
# ///
89
import json
910
from jsonschema import validate, exceptions
1011
from pyld import jsonld
12+
from rdflib import Graph
13+
14+
OSD_NS = 'https://w3id.org/opensyndrome/core/'
1115

1216

1317
# TODO download from definitions in the future
@@ -29,6 +33,7 @@
2933

3034
print("\n--- JSON-LD validation ---")
3135
doc_json['@context'] = local_context['@context']
36+
expanded = None
3237
try:
3338
# check if something was not mapped
3439
expanded = jsonld.expand(doc_json)
@@ -39,3 +44,63 @@
3944

4045
except Exception as exception:
4146
print(f"❌ Erro ao processar JSON-LD: {exception}")
47+
48+
print("\n--- Ontology cross-check (context vs ontology) ---")
49+
ontology = Graph().parse('schemas/v1/ontology.ttl', format='turtle')
50+
defined_terms = {str(s) for s in ontology.subjects() if str(s).startswith(OSD_NS) and str(s) != OSD_NS}
51+
print(f"Ontology declares {len(defined_terms)} osd: terms.")
52+
53+
context_terms: set[str] = set()
54+
def collect_osd_terms(value):
55+
if isinstance(value, str) and value.startswith('osd:'):
56+
context_terms.add(OSD_NS + value.split(':', 1)[1])
57+
elif isinstance(value, dict):
58+
for v in value.values():
59+
collect_osd_terms(v)
60+
elif isinstance(value, list):
61+
for v in value:
62+
collect_osd_terms(v)
63+
64+
for v in local_context['@context'].values():
65+
collect_osd_terms(v)
66+
67+
missing_in_ontology = context_terms - defined_terms
68+
if missing_in_ontology:
69+
print(f"❌ Context references {len(missing_in_ontology)} osd: term(s) not declared in the ontology:")
70+
for term in sorted(missing_in_ontology):
71+
print(f" - {term}")
72+
else:
73+
print(f"✅ All {len(context_terms)} osd: terms in the context are declared in the ontology.")
74+
75+
unused_in_context = defined_terms - context_terms
76+
if unused_in_context:
77+
print(f"ℹ️ {len(unused_in_context)} osd: term(s) declared in the ontology but not used by the context:")
78+
for term in sorted(unused_in_context):
79+
print(f" - {term}")
80+
81+
print("\n--- Example document round-trip (example vs ontology) ---")
82+
if expanded is None:
83+
print("Skipping (JSON-LD expansion failed).")
84+
else:
85+
used_terms: set[str] = set()
86+
def collect_used(value):
87+
if isinstance(value, dict):
88+
for k, v in value.items():
89+
if isinstance(k, str) and k.startswith(OSD_NS):
90+
used_terms.add(k)
91+
collect_used(v)
92+
elif isinstance(value, list):
93+
for v in value:
94+
collect_used(v)
95+
elif isinstance(value, str) and value.startswith(OSD_NS):
96+
used_terms.add(value)
97+
98+
collect_used(expanded)
99+
100+
missing_for_example = used_terms - defined_terms
101+
if missing_for_example:
102+
print(f"❌ Example uses {len(missing_for_example)} osd: term(s) not declared in the ontology:")
103+
for term in sorted(missing_for_example):
104+
print(f" - {term}")
105+
else:
106+
print(f"✅ All {len(used_terms)} osd: terms used in the example are declared in the ontology.")

0 commit comments

Comments
 (0)