An ontology is only useful to software once it is written in an ontology language that tools can parse, query and reason over. For most teams that means the W3C semantic web stack: RDF for the data model, RDFS and OWL 2 for the vocabulary and logic, SHACL for validation and SKOS for lighter taxonomies. Each layer adds something the one below it can't do, and each has a trap that catches newcomers.
Below, each standard gets its job, a Turtle example and the mistake it invites. The article belongs to a series that starts with the overview of what an ontology is and why it matters in data and AI. If you are still deciding whether you need an ontology at all, or whether a taxonomy would do, read ontology vs taxonomy vs knowledge graph first.
What an ontology language has to do
Any ontology language needs to cover four jobs:
- Name things globally, so your
Customernever collides with someone else's. - State facts about those things in a uniform shape.
- Define vocabulary and rules: what classes exist, how they relate, what follows from what.
- Check data against the rules your applications depend on.
The W3C stack splits those jobs across separate standards. That modularity is useful, because you can adopt RDF and RDFS today and add OWL or SHACL only when you need them. It is also confusing, because the same Turtle file can mix all of them.
Ontology language versions in 2026
| Standard | Current Recommendation | In progress | |---|---|---| | RDF | RDF 1.1, February 2014 | RDF 1.2, Candidate Recommendation since April 2026 | | RDFS | RDF Schema 1.1, February 2014 | RDF Schema 1.2 in development | | OWL | OWL 2 Second Edition, December 2012 | None | | SHACL | SHACL, July 2017 | SHACL 1.2 Core, Working Draft (October 2026) | | SPARQL | SPARQL 1.1, March 2013 | SPARQL 1.2 Query, Working Draft (October 2026) | | SKOS | SKOS Reference, August 2009 | None |
For production work, teach and build on the Recommendations. RDF 1.2 is a Candidate Recommendation and SHACL 1.2 is still a Working Draft, and tool support varies, so don't treat them as the current standard until they reach Recommendation.
RDF: everything is a triple
RDF represents information as a graph of triples. Each triple has a subject, a predicate and an object:
- The subject is an IRI or a blank node.
- The predicate is always an IRI.
- The object is an IRI, a blank node or a literal such as a string, number or date.
An IRI is a global identifier, an internationalized form of a URI. Using IRIs means https://example.org/edu#Course is unambiguous anywhere it appears. A literal carries a datatype, so 12 can be an xsd:integer rather than a string.
Turtle is the most readable syntax:
@prefix edu: <https://example.org/edu#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
edu:sparkBasics a edu:Course ;
rdfs:label "Spark Basics"@en ;
edu:hasLesson edu:lesson1, edu:lesson2 .
edu:lesson1 rdfs:label "What is a DataFrame?"@en ;
edu:durationMinutes 12 .
edu:lesson2 rdfs:label "Reading CSV files"@en ;
edu:durationMinutes 18 .
The a keyword is shorthand for rdf:type. A semicolon repeats the subject, and a comma repeats the subject and predicate. The first statement alone expands to four triples.
RDF on its own says nothing about what Course or hasLesson mean. It is a data model, not yet an ontology language. RDF 1.2 adds triple terms and rdf:reifies, a compact replacement for RDF 1.1's rdf:Statement reification, so you can make statements about a triple (who asserted it, when, with what confidence). That will matter for provenance in AI pipelines, but wait for your triple store to support it before you rely on it.
RDFS: classes and properties
RDF Schema is the first real vocabulary layer. Its core terms are:
rdfs:Classandrdfs:subClassOffor class hierarchies (subclass is transitive).rdf:Propertyandrdfs:subPropertyOffor property hierarchies.rdfs:domainandrdfs:rangeto say what kind of thing a property links.rdfs:labelandrdfs:commentfor human-readable text.
edu:Instructor rdfs:subClassOf edu:Person .
edu:teaches rdfs:domain edu:Instructor ;
rdfs:range edu:Course .
Here is the trap. Domain and range in RDFS are inference rules, not constraints. If your data says edu:bob edu:teaches edu:sparkBasics, an RDFS reasoner does not complain that Bob isn't declared an instructor. It concludes that Bob is an instructor, and therefore a person. Developers coming from SQL expect a foreign-key error and get a new fact instead. Rejecting data is SHACL's job.
For catalogs and metadata registries, RDFS plus a few OWL terms is often all you need.
OWL 2: logic and reasoning
OWL 2 is the full ontology language. It keeps everything from RDFS and adds:
- Class expressions: intersection, union and complement ("a premium customer is a customer and has an active premium contract").
- Restrictions: existential (
someValuesFrom), universal (allValuesFrom) and cardinality ("exactly one billing account"). - Equivalence and disjointness between classes.
- Property characteristics: inverse, transitive, symmetric, functional.
- Identity:
owl:sameAsandowl:differentFrom. - OWL 2 additions over OWL 1: keys, property chains and qualified cardinality.
@prefix owl: <http://www.w3.org/2002/07/owl#> .
edu:PremiumLearner owl:equivalentClass [
a owl:Class ;
owl:intersectionOf ( edu:Learner
[ a owl:Restriction ;
owl:onProperty edu:hasSubscription ;
owl:someValuesFrom edu:PremiumPlan ] )
] .
With that axiom, a reasoner classifies any learner with a premium plan as a PremiumLearner automatically. Nobody has to maintain that list.
OWL 2 profiles
Full OWL 2 DL reasoning can be expensive. The W3C defines three profiles that trade expressiveness for speed:
| Profile | Built for | Typical use | |---|---|---| | OWL 2 EL | Very large class hierarchies, polynomial-time reasoning | Clinical terminologies such as SNOMED CT | | OWL 2 QL | Querying large instance data by rewriting queries into SQL | Virtual knowledge graphs over relational databases | | OWL 2 RL | Rule-based reasoning engines | Triple stores with forward-chaining rules |
Pick the profile from your workload. If the ontology sits over relational data and you query it live, OWL 2 QL is what tools such as Ontop support, as described in ontology-based data integration. If you have a huge taxonomy-like model, OWL 2 EL with a reasoner such as ELK classifies it quickly. HermiT and Pellet handle full OWL 2 DL for smaller models.
The open-world assumption
OWL reasoning follows the open-world assumption. A fact that isn't stated is unknown, not false. If an axiom says every course has at least one lesson and a course has none recorded, the reasoner does not report an error; it assumes the lesson exists and simply isn't in your data.
OWL also has no unique-name assumption. Two different IRIs might refer to the same individual unless you say otherwise with owl:differentFrom. And owl:sameAs asserts full identity, not similarity. Linking two records with sameAs because they look alike merges every fact about them, and it can quietly corrupt a knowledge graph.
This behaviour is exactly right for integrating incomplete information from many sources. It is exactly wrong for checking that a form was filled in correctly. That gap is why SHACL exists.
SHACL: validating data
SHACL, the Shapes Constraint Language, validates an RDF data graph against a shapes graph. It is closed-world in practice: if a required value is missing, SHACL reports it.
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
edu:LessonShape a sh:NodeShape ;
sh:targetClass edu:Lesson ;
sh:property [
sh:path edu:durationMinutes ;
sh:datatype xsd:integer ;
sh:minCount 1 ;
sh:maxCount 1 ;
] .
A node shape targets a set of focus nodes, here every edu:Lesson. A property shape uses sh:path to constrain the values reached through a property. Every implementation must support SHACL Core; SHACL-SPARQL adds custom constraints written as SPARQL queries.
The clean way to think about it: OWL and RDFS describe what the world is like and let you infer more. SHACL describes what your data must look like before an application accepts it. Projects that both integrate data and feed applications usually need both. SHACL is also the natural gate for LLM-generated triples, a pattern covered in ontologies and LLMs.
Do you need OWL, or is RDFS enough?
For most first projects, RDFS is enough. The question to ask is whether you need the machine to conclude something you did not write down. If every fact you care about is stated explicitly in the data, and your applications only need to know which classes and properties exist, RDFS plus SHACL covers it. Catalogs, metadata registries and most data integration layers work this way.
OWL 2 earns its place in three situations. The first is automatic classification: you want records to land in the right class based on their properties, such as flagging every account with an overdue invoice and an open dispute as AtRiskAccount. The second is reconciling sources: two systems describe the same concept with different terms, and owl:equivalentClass or owl:equivalentProperty lets queries treat them as one. The third is consistency checking across a large model, where disjointness axioms catch modelling errors before they reach production. Clinical terminologies rely on this heavily.
The cost is real. OWL axioms are harder to read than RDFS, reasoners can be slow on large or badly designed models, and the open-world assumption surprises developers. A good compromise is to keep the core ontology in RDFS, add a small number of OWL axioms where inference clearly pays off, and test reasoning time on realistic data before you commit to more.
How the layers work together
A single example shows each standard doing its own job. Imagine a learning platform that stores courses and lessons as RDF.
- RDF holds the facts: Spark Basics is a course, lesson 1 is part of it, lesson 1 lasts 12 minutes.
- RDFS says what those terms mean:
Instructoris a subclass ofPerson, andhasLessonlinks a course to a lesson. - OWL 2 adds a rule: a
HandsOnCourseis any course with at least one lesson of typeLabLesson. A reasoner can then classify courses without anyone tagging them by hand. (A rule like "all lessons under 15 minutes" would not work here: under the open-world assumption the reasoner can't rule out a longer lesson that isn't recorded.) - SHACL guards the pipeline: every lesson must have exactly one integer duration, or the load fails with a readable report.
- SKOS carries the topic taxonomy that drives the course catalog menu: Data Engineering > Spark > DataFrames.
- SPARQL answers the product team's questions across all of it.
None of these replaces another. A frequent source of trouble is one standard being asked to do another's job, typically OWL being used for validation or SKOS being used for reasoning.
SKOS: for taxonomies and thesauri
SKOS sits slightly apart from the rest. It models concept schemes, taxonomies and thesauri with skos:Concept, skos:broader, skos:narrower, skos:related and labels. It is defined in OWL, but the W3C is clear that it isn't a formal knowledge representation language. Use it for navigation and tagging vocabularies, and link its concepts to OWL classes when you need reasoning.
SPARQL: the query language
SPARQL 1.1 is the query language for all of the above. It matches graph patterns, much like SQL matches rows:
PREFIX edu: <https://example.org/edu#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?lesson ?minutes
WHERE {
edu:sparkBasics edu:hasLesson ?l .
?l rdfs:label ?lesson ;
edu:durationMinutes ?minutes .
}
ORDER BY ?minutes
Run against the Turtle data from the RDF section (here with RDFLib 7.6.0), it returns:
lesson | minutes
What is a DataFrame? | 12
Reading CSV files | 18
It also supports property paths, aggregates, federated queries across endpoints with SERVICE, and SPARQL Update for writes. If an ontology can't answer your competency questions (the business questions the model is meant to answer) through SPARQL, it is missing something.
Choosing an ontology language for your project
Most teams don't choose one ontology language; they choose how far up the stack to go:
- Start with RDF and RDFS. Classes, subclasses, properties, labels. For many integration and catalog projects, that is enough to begin.
- Add SHACL as soon as data feeds an application. For that kind of data, validation usually catches more problems than reasoning does.
- Add OWL 2 axioms when you need inference: automatic classification, equivalence across sources, or contradiction detection. Stay within a profile if performance matters.
- Use SKOS for vocabularies maintained by content or business teams.
Property-graph databases such as Neo4j use their own models rather than RDF. They are fine for many graph applications, but they have no standard equivalent of OWL reasoning. If you use one, keep the ontology in OWL or a simple schema file and use it to drive the graph's labels and relationship types. The GraphRAG pattern in ontology-driven GraphRAG works this way.
Common mistakes
- Expecting
rdfs:domainandrdfs:rangeto reject bad data. - Expecting OWL to flag missing values under the open-world assumption.
- Using
owl:sameAsfor "similar to". - Building full OWL 2 DL axioms that your query engine's profile ignores.
- Treating draft versions as current Recommendations.
- Writing IRIs by hand without a consistent namespace. Pick one base IRI, end it with
#or/, and generate terms from it, or you'll end up withhttps://example.org/edu#Courseandhttps://example.org/edu/Courseas two unrelated classes. - Modelling every lookup value as an OWL class. Statuses and categories are usually better as SKOS concepts or individuals.
Try it yourself
Reading Turtle only gets you so far. The companion tutorial, build an ontology in Python with RDFLib, creates classes and properties in code, loads instance data, runs SPARQL, shows RDFS inference adding facts, and uses SHACL to catch a missing value.
Key takeaways
- RDF is the data model: triples of IRIs, blank nodes and literals.
- RDFS adds classes, subclasses, domain and range, which infer rather than constrain.
- OWL 2 adds logic for automatic classification, equivalence and contradiction detection, with EL, QL and RL profiles for scale.
- SHACL validates data under closed-world rules and is the right tool for rejecting bad input.
- SKOS is for taxonomies, and SPARQL queries all of it.
- Build on the current Recommendations: RDF 1.1, OWL 2, SHACL (2017) and SPARQL 1.1.
