Overview

When working with data in RDF (Resource Description Framework), two mechanisms come into play: “RDFS (RDF Schema)” and “SHACL (Shapes Constraint Language)”. Both can define constraints on properties and classes, but their purposes and behaviors are completely different.

This article answers the following commonly confused questions:

  • What is the difference between rdfs:domain / rdfs:range and SHACL’s sh:class / sh:datatype?
  • Is it acceptable to set SHACL constraints that differ from the RDFS range?
  • Is it problematic to specify a datatype (xsd:string) in SHACL when the range is a class (foaf:Person)?

1. The Fundamental Difference Between RDFS and SHACL

RDFS: For Inference

RDFS is a declaration that says “if this property is used, the following knowledge can be derived.”

# RDFS schema definition
ex:author rdfs:domain ex:Book ;
          rdfs:range ex:Person .

Meaning:

  • When ex:author is used, the subject is automatically inferred to be a member of ex:Book
  • The object is automatically inferred to be a member of ex:Person
# Original data
ex:book1 ex:author ex:john .

# Knowledge automatically derived by the inference engine
ex:book1 a ex:Book .      # Inferred from domain
ex:john a ex:Person .     # Inferred from range

Characteristics:

  • Generates new knowledge (executed by the inference engine)
  • Open World Assumption
  • No concept of errors
  • A declaration of “if used, this is also true”

SHACL: For Validation

SHACL is a constraint that “checks whether existing data conforms to these rules.”

# SHACL constraint definition
ex:BookShape
  a sh:NodeShape ;
  sh:targetClass ex:Book ;
  sh:property [
    sh:path ex:author ;
    sh:class ex:Person ;      # <- "Value must be ex:Person"
    sh:minCount 1 ;           # <- "At least one required"
    sh:maxCount 3             # <- "Maximum of three"
  ] .

Meaning: “Data should conform to these rules”

# Test data
ex:book1 ex:author "John Smith" .   # Violation! A string, not a Person

# Validation result (validation report)
sh:ValidationReport [
  sh:conforms false ;
  sh:result [
    sh:resultSeverity sh:Violation ;
    sh:focusNode ex:book1 ;
    sh:resultPath ex:author ;
    sh:value "John Smith" ;
    sh:resultMessage "Value is not a member of class ex:Person"
  ]
] .

Characteristics:

  • Detects rule violations (executed by the validation engine)
  • Closed World Assumption-like (validates what is explicitly stated in rules)
  • Generates error reports
  • A constraint of “data should be like this”

2. Comparison Table

AspectRDFS domain/rangeSHACL property shape
PurposeSemantic definition / inferenceData validation
BehaviorGenerates new knowledgeDetects rule violations
PhilosophyOpen WorldClosed World-like
TimingSchema design timeData registration / validation time
ExecutorInference engineValidation engine
ResultInferred triplesValidation report
FlexibilityMore lenientMore strict

3. Practical Usage Patterns

Pattern 1: Define Semantics with RDFS, Ensure Quality with SHACL

This is the most recommended combination.

# 1. Define semantics with RDFS (vocabulary level)
ex:hasContact rdfs:domain ex:Person ;
              rdfs:range ex:ContactInfo ;
              rdfs:label "has contact" .

# 2. Ensure data quality with SHACL (profile level)
ex:PersonShape
  a sh:NodeShape ;
  sh:targetClass ex:Person ;
  sh:property [
    sh:path ex:hasContact ;
    sh:class ex:ContactInfo ;  # Corresponds to RDFS range
    sh:minCount 1 ;            # But SHACL adds "required"
    sh:maxCount 3              # And adds "maximum 3" constraint
  ] .

ex:ContactInfoShape
  a sh:NodeShape ;
  sh:targetClass ex:ContactInfo ;
  sh:property [
    sh:path ex:email ;
    sh:datatype xsd:string ;   # Datatype specification
    sh:pattern "^[^@]+@[^@]+$" ;  # Email format regex
    sh:minCount 1
  ] .

Pattern 2: Different Constraints Per Profile

The same vocabulary can be used with different constraints depending on the use case.

# Vocabulary defined generically
ex:author rdfs:range foaf:Agent .  # Person or Organization

# Paper profile - only individuals required
:PaperProfile
  sh:property [
    sh:path ex:author ;
    sh:class foaf:Person ;  # Stricter than Agent
    sh:minCount 1
  ] .

# Report profile - only organizations required
:ReportProfile
  sh:property [
    sh:path ex:author ;
    sh:class foaf:Organization ;  # Stricter than Agent
    sh:minCount 1
  ] .

# Book profile - either is acceptable
:BookProfile
  sh:property [
    sh:path ex:author ;
    sh:class foaf:Agent ;  # Same as range
    sh:minCount 1
  ] .

4. Frequently Asked Questions

Q1: Can SHACL constraints differ from the RDFS range?

A: Yes, and it is often recommended.

However, SHACL constraints should be the same as or stricter than the range.

# RDFS - broad range
ex:creator rdfs:range foaf:Agent .   # Person or Organization

# SHACL - more specific
:ProfileShape
  sh:property [
    sh:path ex:creator ;
    sh:class foaf:Person ;  # Narrowed down to a subclass of Agent
    sh:minCount 1
  ] .
# RDFS - general literal
ex:value rdfs:range rdfs:Literal .

# SHACL - specific datatype
:ProfileShape
  sh:property [
    sh:path ex:value ;
    sh:datatype xsd:integer ;  # Specialized from Literal to integer
    sh:minInclusive 0
  ] .

Pattern to Avoid: Making It Broader Than range

# RDFS
ex:author rdfs:range foaf:Person .

# SHACL
:ProfileShape
  sh:property [
    sh:path ex:author ;
    sh:class foaf:Agent  # Broader than Person (not recommended)
  ] .

This is not logically contradictory, but it causes confusion.

Q2: Is it problematic to specify a datatype in SHACL when the range is a class?

A: Yes, this is a semantic contradiction. Absolutely avoid it.

Problematic Example

# Vocabulary definition - expects a class (URI reference)
ex:author rdfs:range foaf:Person .

# Profile - requires a datatype (literal)
:ProfileShape
  sh:property [
    sh:path ex:author ;
    sh:datatype xsd:string  # Contradiction!
  ] .

Why this is problematic:

  • rdfs:range foaf:Person: The value is an instance of foaf:Person (URI reference)
  • sh:datatype xsd:string: The value is a string literal

These two are incompatible as types:

# Data conforming to RDFS (URI reference)
ex:book1 ex:author  .
# RDFS: OK, SHACL: NG

# Data conforming to SHACL (string literal)
ex:book1 ex:author "John Doe" .
# RDFS: NG, SHACL: OK

# -> No data can satisfy both!

Correct Pattern 1: Use URI References

# Vocabulary
ex:author rdfs:range foaf:Person .

# Profile
sh:property [
  sh:path ex:author ;
  sh:class foaf:Person ;      # Matches range
  sh:nodeKind sh:IRI ;        # Explicitly a URI reference
  sh:minCount 1
] .

# Data
ex:book1 ex:author  .
 a foaf:Person ;
  foaf:name "John Doe" .

Correct Pattern 2: Use Literals

# Vocabulary
ex:authorName rdfs:range xsd:string .  # Literal

# Profile
sh:property [
  sh:path ex:authorName ;
  sh:datatype xsd:string ;    # Matches range
  sh:minCount 1 ;
  sh:maxLength 200
] .

# Data
ex:book1 ex:authorName "John Doe" .
# Vocabulary - define two separate properties
ex:author rdfs:range foaf:Person .     # For URI references
ex:authorName rdfs:range xsd:string .  # For string labels

# Profile
sh:property [
  sh:path ex:author ;
  sh:class foaf:Person ;
  sh:nodeKind sh:IRI
] ;
sh:property [
  sh:path ex:authorName ;
  sh:datatype xsd:string ;
  sh:minCount 1  # This one is required
] .

# Data
ex:book1 ex:author  ;
         ex:authorName "John Doe" .

Q3: What is type category consistency?

A: RDFS range and SHACL constraints must be in the same “type category”.

rdfs:rangeSHACL constraintType categoryEvaluation
foaf:Personsh:class foaf:PersonClass <-> ClassConsistent
foaf:Personsh:class foaf:AgentClass <-> ClassMore lenient
foaf:Agentsh:class foaf:PersonClass <-> ClassStricter (recommended)
foaf:Personsh:datatype xsd:stringClass <-> DatatypeContradiction
xsd:stringsh:datatype xsd:integerDatatype <-> DatatypeContradiction
rdfs:Literalsh:datatype xsd:stringDatatype <-> DatatypeSpecialization (recommended)

5. Practical Application Example

Case: Metadata Management System

# === Defined in Vocabulary Management Screen (RDFS) ===

# Define generic properties
myv:subject
  rdfs:domain myv:Resource ;
  rdfs:range skos:Concept ;    # Broadly accepts "concepts"
  rdfs:label "subject" .

myv:creator
  rdfs:domain myv:Resource ;
  rdfs:range foaf:Agent ;      # Person or Organization
  rdfs:label "creator" .

myv:format
  rdfs:domain myv:Resource ;
  rdfs:range dcterms:MediaTypeOrExtent ;
  rdfs:label "format" .


# === Constrained in Profile Management Screen (SHACL) ===

# Dataset profile - strict constraints
:DatasetProfile
  a sh:NodeShape ;
  sh:targetClass myv:Dataset ;
  sh:property [
    sh:path myv:subject ;
    sh:class myv:NDCConcept ;    # Narrowed to subclass of skos:Concept
    sh:node [
      sh:property [
        sh:path skos:inScheme ;
        sh:hasValue   # NDC classification only
      ]
    ] ;
    sh:minCount 1 ;              # Required
    sh:maxCount 10
  ] ;
  sh:property [
    sh:path myv:creator ;
    sh:class foaf:Person ;       # Narrowed from foaf:Agent to Person
    sh:nodeKind sh:IRI ;
    sh:minCount 1                # Required
  ] ;
  sh:property [
    sh:path myv:format ;
    sh:datatype xsd:string ;     # Specialized from MediaTypeOrExtent to string
    sh:pattern "^[a-z]+/[a-z0-9+.-]+$" ;  # MIME type format
    sh:minCount 1
  ] .

# Image profile - more flexible constraints
:ImageProfile
  a sh:NodeShape ;
  sh:targetClass myv:Image ;
  sh:property [
    sh:path myv:subject ;
    sh:class skos:Concept ;      # Same as range (any concept scheme)
    sh:minCount 1
  ] ;
  sh:property [
    sh:path myv:creator ;
    sh:or (
      [ sh:class foaf:Person ]
      [ sh:class foaf:Organization ]  # Organizations also allowed
    ) ;
    sh:minCount 1
  ] ;
  sh:property [
    sh:path myv:format ;
    sh:in ( "image/jpeg" "image/png" "image/gif" ) ;  # List of allowed values
    sh:minCount 1 ;
    sh:maxCount 1
  ] .

6. Summary: Design Guidelines

Vocabulary Design (RDFS) Guidelines

  1. Define as generically as possible (maximize reusability)
  2. Keep domain/range flexible (consider future extensions)
  3. Make semantic relationships explicit (provide information usable for inference)

Profile Design (SHACL) Guidelines

  1. Set specific constraints according to use case (ensure data quality)
  2. Keep constraints the same as or stricter than the RDFS range (never make them more lenient)
  3. Maintain type category consistency (class <-> class, datatype <-> datatype)
  4. Clearly define required/optional and cardinality limits (reflect operational rules)

Prohibited Practices

Specifying a datatype (xsd:string) in SHACL when RDFS uses a class (foaf:Person) Specifying a different datatype (xsd:integer) in SHACL when RDFS uses a datatype (xsd:string) Making SHACL constraints more lenient than the RDFS range

Use RDFS generically, SHACL specifically Narrow down using subclasses and subproperties Set different constraints for each profile Manage URI references and literals as separate properties

7. Further Reading