Loading the Schema from a SPARQL Endpoint
When a SPARQL 1.1 endpoint (e.g. Apache Jena Fuseki)
hosts the CGMES RDFS schema as named graphs, CIMVocabCheck can discover the schema — and the
per-graph profile scope — automatically. No namedGraphs
config required.
The endpoint names where the schema lives. CIMVocabCheck reads the RDFS profiles from it; it never validates live instance data and never executes your query against it.
How it works
EndpointSchemaLoader:
- enumerates the schema graphs — those declaring an
rdfs:Class/owl:Ontology— and builds the index from them; - classifies every other (instance) graph by sampling up to 400 of its terms — the predicates
it uses and its
rdf:typeobjects — and looking each one up in the schema. A term declared by exactly one profile is discriminating (the "this property is in EQ but in no other profile" signal); the graph is assigned to the profile with the most discriminating terms, with the total number of matching terms as a tie-break. A graph whose sampled terms match no profile is left unmatched.
Classification only ever samples a graph to decide which profile it is — it never validates the instance data.
Per-graph validation — terms used in the wrong graph become errors
Once every graph is mapped to a profile, your query is validated per graph: the terms inside a
GRAPH <g> { ... } block are checked against only the profile detected for <g>, not the union
of all profiles. This is what makes auto-resolution useful — it catches terms used in the wrong
graph.
For example, if the dataset's equipment graph was detected as Equipment (EQ) and the query uses a Topology-only property inside it:
SELECT * WHERE {
GRAPH <urn:uuid:...-eq> {
?n cim:TopologicalNode.nominalVoltage ?v . # a TP property, inside the EQ graph
}
}
CIMVocabCheck reports UNKNOWN_PROPERTY for
cim:TopologicalNode.nominalVoltage against the EQ graph — and because the property does exist in
the Topology profile, the finding lists Topology in its
found in other profiles hint, telling you the term is real but
sits in the wrong graph. Graphs the query references that were left unmatched (or that don't
exist in the dataset) produce a GRAPH_NOT_CONFIGURED warning,
and terms inside them cannot be resolved.
Auto-resolution is an endpoint feature. With a file-based schema and no
namedGraphs mapping, every term is validated against
all loaded profiles at once, so there are no per-graph cross-profile errors. Per-graph scoping
happens either here (auto-detected from the endpoint) or when you map graphs to profiles by hand
with namedGraphs.
From Java
import de.soptim.opencgmes.cimvocabcheck.core.schema.EndpointSchema;
import de.soptim.opencgmes.cimvocabcheck.core.schema.EndpointSchemaLoader;
import de.soptim.opencgmes.cimvocabcheck.core.SparqlValidationApi;
import de.soptim.opencgmes.cimvocabcheck.core.SparqlValidationResult;
import java.time.Duration;
EndpointSchema es = EndpointSchemaLoader.loadFromEndpoint(
"http://localhost:3030/cgmes/query", Duration.ofSeconds(30));
if (!es.hasSchema()) {
// Reachable, but no CIM schema graphs found — warn and fall back to syntax-only.
SparqlValidationResult r = SparqlValidationApi.checkSyntaxOnly(queryText);
} else {
SparqlValidationApi api = new SparqlValidationApi(es.index());
// es.namedGraphScope() maps each instance graph to its detected profile(s):
SparqlValidationResult r = api.validateSparql(queryText, es.namedGraphScope());
// es.unmatchedGraphs() lists instance graphs that matched no known profile.
}
A Fuseki …/update URL is tolerated (its …/query sibling is used automatically). For in-process
datasets or tests, pass a SparqlGraphSource to EndpointSchemaLoader.load(...) instead.
!es.hasSchema() covers two different situations, both distinguishable via es.schemaGraphNames()
and es.unresolvedReason():
- No schema-like graphs at all (
schemaGraphNames()empty) — the endpoint genuinely hosts nordfs:Class/owl:Ontologygraph. - Schema graphs found, but none resolved to a CIM profile (
schemaGraphNames()non-empty,unresolvedReason()set) — almost always an unrecognizedcimnamespace. Register it withcimNamespacesinopencgmes.jsoncand reload.
The CLI and language server print distinct warnings for each case rather than a single generic "no schema" message.
From the CLI
java -jar cimvocabcheck-cli.jar \
--endpoint http://localhost:3030/cgmes/query path/to/query.rq
If the endpoint exposes no CIM schema graphs, validation falls back to a syntax-only check with
a warning. Pass --strict-endpoint to make that case a hard failure (exit 2) instead — so a
misconfigured pipeline breaks visibly rather than silently checking only syntax. See the
CLI page.
From a SPARQL Notebook cell
In CIMNotebook, a notebook cell can name its schema endpoint inline:
# [endpoint=http://localhost:3030/cgmes/query]
SELECT * WHERE { ?s a cim:ACLineSegment }
Assumptions & limitations
- The CGMES profiles must be stored in per-profile named graphs (graphs declaring
rdfs:Class/owl:Ontology). A schema kept entirely in the default graph, or mixed with instance data in one graph, is not discovered. - A profile graph that declares neither an
rdfs:Classnor anowl:Ontology(rare — e.g. some header/boundary profiles) is not picked up by the enumeration filter. - Graphs fetched over SPARQL usually carry no prefix declarations, so a custom
cimnamespace can only be recognized once it's registered — viacimNamespaces— before the endpoint load runs; there's no way to auto-detect an unregistered custom namespace from namespace-less graph content alone.
See Known limitations for the broader picture.