SHACL: Shapes Constraint Language (SHACL) for Ruby
100% pure Ruby with minimal dependencies and no bloat.
Fully compatible with SHACL Core SHACL.
Partially compatible with SHACL-SPARQL SHACL.
100% free and unencumbered public domain software.
gem install shacl
The SHACL gem implements a SHACL Shape Expression engine.
require 'linkeddata' require 'shacl' graph = RDF::Graph.load("etc/doap.ttl") shacl = .("etc/doap.shacl") report = shacl.execute(graph) #=> ValidationReport(conform?, results*)
TODO: When the
linkeddata gem is installed, RDF.rb includes a
rdf executable which acts as a wrapper to perform a number of different operations on RDF files, including SHACL. The commands specific to SHACL is
shacl: Validate repository given shape
Using this command requires
shacl, which references a URI or file path to the SHACL shapes graph. Other options are
rdf shacl https://ruby-rdf.github.io/shacl/etc/doap.ttl \ --shape https://ruby-rdf.github.io/shacl/etc/doap-shape.ttl
The result will add the SHACL validation report to the output graph, optionally replacing the graph with the results, expressing the results as an s-expression, or adding the results as output messages.
Similar to the ShEx gem and to the general strategy for querying graphs in the SPARQL gem, the strategy is to parse SHACL shapes into executable operators, which are called recursively to create result sets corresponding to matched nodes and properties.
Evaluating the shapes against a graph results in aindicating conformance, along with a set of individual instances.
The resulting validation report can be compared with other validation reports, used as native Ruby objects, serialized to s-expressions, or used as an RDF::Enumerable to retrieve the RDF representation of the report, as defined in SHACL Spec.
SHACL-SPARQL variable bindings pass a solution to the query composed of the necessary bindings rather than rewrite the query. Supports SHACL-based Constraints.
Matching Entailed Triples
Many tests check for entailed triples, such as entailed super-classes of explicit
rdf:type values. If this is required for a given application, the RDF::Reasoner gem can be used to create such entailed triples.
require 'shacl' require 'rdf/reasoner' RDF::Reasoner.apply(:rdfs) graph = RDF::Graph.load("etc/doap.ttl") graph.entail! shacl = .("etc/doap.shacl") results = shacl.execute(graph) #=> [ValidationResult, ...]
This implementation is certainly not performant. Some things that can be be considered in future versions:
Index shapes on
targetClassand other targets to allow a more efficient query to find relevant resources in the data graph and not simply iterrate through each top-level shape.
Cache target nodes as JSON-LD to reduce the need to separately query for each constraint.
Reasoner should support limited RDFS/OWL entailment from the data graph, not just pre-defined vocabularies.
More SHACL Advanced Features.
Support the SHACL Compact Syntax.
The recommended installation method is via RubyGems. To install the latest official release of RDF.rb, do:
% [sudo] gem install shacl
To get a local working copy of the development repository, do:
% git clone git://github.com/ruby-rdf/shacl.git
Alternatively, download the latest development version as a tarball as follows:
% wget https://github.com/ruby-rdf/shacl/tarball/master
This repository uses Git Flow to mange development and release activity. All submissions must be on a feature branch based on the develop branch to ease staging and integration.
Do your best to adhere to the existing coding conventions and idioms.
Don’t use hard tabs, and don’t leave trailing whitespace on any line. Before committing, run
git diff --checkto make sure of this.
Don’t touch the
VERSIONfiles. If you need to change them, do so on your private branch only.
Do feel free to add yourself to the
CREDITSfile and the corresponding list in the the
README. Alphabetical order applies.
Don’t touch the
AUTHORSfile. If your contributions are significant enough, be assured we will eventually add you in there.
Do note that in order for us to merge any non-trivial changes (as a rule of thumb, additions larger than about 15 lines of code), we need an explicit public domain dedication on record from you, which you will be asked to agree to on the first commit to a repo within the organization. Note that the agreement applies to all repos in the Ruby RDF organization.