SHACL Compact Syntax: Quick Tutorial

The SHACL Shapes Constraint Language includes a Compact Syntax for those who prefer to define data shapes using a simple textual notation. This syntax is heavily inspired by ShEx which was one of the input specifications to the W3C group that worked out SHACL. SHACL is a very rich language with many possibilities. Compact syntax does not cover all available options, but it covers well frequently used features of SHACL. As you can guess from its name, the main goal for SHACL Compact Syntax was to have a simpler and less verbose textual notation than RDF e.g., Turtle serialization of SHACL.

Graphical tools such as TopBraid Composer for the technical users and TopBraid EDG for either technical or business users remain to be the best approaches for building SHACL models. However, users with preference for simple text editors (like Notepad) will find SHACL Compact Syntax to be a good option for quickly capturing typical schemas. Such users may, for example, use this approach as input to other tools such as validators or data graph browsers and editors.

Here is an example SHACL Compact Syntax file (skos-compact.shaclc):

BASE <http://example.org/skos-compact>
    
IMPORTS <http://www.w3.org/2004/02/skos/core>
    
PREFIX ex: <http://example.org/skos-compact#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
    
shape ex:ConceptShape -> skos:Concept {
    skos:prefLabel xsd:string|rdf:langString .
    skos:definition xsd:string|rdf:langString|rdf:HTML .
    skos:broader @ex:ConceptShape .
    ^skos:hasTopConcept [0..1] .
}
    
shape ex:ConceptSchemeShape -> skos:ConceptScheme {
    skos:hasTopConcept IRI skos:Concept @ex:ConceptShape .
}

The example above defines two SHACL shapes (ex:ConceptShape and ex:ConceptSchemeShape) that declare some commonly used SKOS properties. Let’s go through this file step by step:

  • The optional BASE declaration defines the name (URI) of the shapes graph itself, in case you want to reference it from elsewhere.
  • IMPORTS is used to state that this shapes graph includes the definitions from another graph, e.g. another SHACL or RDFS/OWL file with a specified BASE.
  • PREFIX declares prefixes to abbreviate the example and SKOS namespaces. The prefixes rdf, rdfs, sh and xsd are always present.

The shape ex:ConceptShape is declared to apply to all instances of the class skos:Concept. In more technical words, the -> arrow defines a sh:targetClass statement. 

Each row inside of the { … } curly braces declares one property that target resources (in this case, instances of skos:Concept) may have. The property skos:prefLabel is declared to have values that are either xsd:string or rdf:langString literals, i.e. they may be strings that have a language tag. Similarly, skos:definition may take strings, langStrings or HTML literals as values. The property skos:broader is constrained to resources that also fulfill the constraints of ex:ConceptShape – technically this is a sh:node constraint. Finally, there is a constraint on skos:hasTopConcept but walked in the inverse direction (expressed using the ^). This means that each skos:Concept can be the top concept of at most one concept scheme. The Compact Syntax supports complex SPARQL-like path expressions in addition to simple properties.

The second shape, ex:ConceptSchemeShape, applies to all instances of skos:ConceptScheme. The property skos:hasTopConcept can only take IRIs as values (i.e. neither literals nor blank nodes), the values must be instances of skos:Concept and conform to the shape ex:ConceptShape.

You can use files such as the example above in TopBraid Composer: put them into the Workspace as a file ending with .shaclc and then drag that file into the Imports panel of another file. You cannot open these .shaclc files with double-click because they are considered read-only by TopBraid – the whole point of the Compact Syntax is to be attractive to text editors.

If you are a programmer, you can also parse SHACLC files using the open source TopBraid SHACL API (in Java).

To finish this mini tutorial, here is the previous example parsed by TopBraid into Turtle format:

# baseURI: http://example.org/skos-compact
# imports: http://datashapes.org/dash
# imports: http://www.w3.org/2004/02/skos/core
# prefix: ex
    
@prefix ex: <http://example.org/skos-compact#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
    
<http://example.org/skos-compact>
  a owl:Ontology ;
  owl:imports <http://datashapes.org/dash> ;
  owl:imports <http://www.w3.org/2004/02/skos/core> .
    
ex:ConceptSchemeShape
  a sh:NodeShape ;
  sh:property [
      sh:path skos:hasTopConcept ;
      sh:class skos:Concept ;
      sh:node ex:ConceptShape ;
      sh:nodeKind sh:IRI ;
    ] ;
  sh:targetClass skos:ConceptScheme .
    
ex:ConceptShape
  a sh:NodeShape ;
  sh:property [
      sh:path skos:broader ;
      sh:node ex:ConceptShape ;
    ] ;
  sh:property [
      sh:path skos:definition ;
      sh:or (
          [
            sh:datatype xsd:string ;
          ]
          [
            sh:datatype rdf:langString ;
          ]
          [
            sh:datatype rdf:HTML ;
          ]
        ) ;
    ] ;
  sh:property [
      sh:path skos:prefLabel ;
      sh:or (
          [
            sh:datatype xsd:string ;
          ]
          [
            sh:datatype rdf:langString ;
          ]
        ) ;
    ] ;
  sh:property [
      sh:path [
          sh:inversePath skos:hasTopConcept ;
        ] ;
      sh:maxCount 1 ;
    ] ;
  sh:targetClass skos:Concept .