|
3 | 3 | # dependencies = [ |
4 | 4 | # "jsonschema>=4.26.0", |
5 | 5 | # "pyld>=2.0.4", |
| 6 | +# "rdflib>=7.0.0", |
6 | 7 | # ] |
7 | 8 | # /// |
8 | 9 | import json |
9 | 10 | from jsonschema import validate, exceptions |
10 | 11 | from pyld import jsonld |
| 12 | +from rdflib import Graph |
| 13 | + |
| 14 | +OSD_NS = 'https://w3id.org/opensyndrome/core/' |
11 | 15 |
|
12 | 16 |
|
13 | 17 | # TODO download from definitions in the future |
|
29 | 33 |
|
30 | 34 | print("\n--- JSON-LD validation ---") |
31 | 35 | doc_json['@context'] = local_context['@context'] |
| 36 | +expanded = None |
32 | 37 | try: |
33 | 38 | # check if something was not mapped |
34 | 39 | expanded = jsonld.expand(doc_json) |
|
39 | 44 |
|
40 | 45 | except Exception as exception: |
41 | 46 | 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