This is a working document. The contents are expected to go to some other document. For the moment, keeping this document short minimizes respec race conditions.
This document defines a mapping from the ShEx JSON syntax to the SHACL abstract syntax. The input schema is expressed in this style:
| Schema | { | shapes:{shapeLabel->shapeExpr}? } |
|---|
and the output schema in this style:
shapes:Set[Shape]Examples provide mappings from ShExC to SHACL schemas.
A ShEx schema is translated to a SHACL schema by recursively applying the construction rules below:
| Schema | { | shapes:{shapeLabel->shapeExpr}? } |
|---|---|---|
| shapeLabel | = | IRI | BNODE ; |
| shapeExpr | = | ShapeOr | ShapeAnd | ShapeNot | NodeConstraint | Shape | ShapeRef | ShapeExternal ; |
|---|
shapes:Set[Shape]label:IRI|BNode, targets:Set[Target], filters:Set[Shape], constraints:Set[Test]The map ShEx shapes is treated as a set of (shapeLabel, shapeExpr) pairs. The label is used as the subject node of SHACL/RDF Shape constructions.
ShEx:
<IssueShape> { ... }
SHACL:
<IssueShape> a sh:Shape ...
| ShapeOr | { | shapeExprs:[shapeExpr] } |
|---|
shapes:Set[Shape]
Each shapeExpr in shapeExprs is consructed as a Shape in shapes.
ShEx:
<User> @<Person> OR <Customer>
SHACL:
<User> sh:constraint [ sh:or (<Person> <Customer>) ]
| ShapeAnd | { | shapeExprs:[shapeExpr] } |
|---|
shapes:Set[Shape]
Each shapeExpr in shapeExprs is consructed as a Shape in shapes.
ShEx:
<User> @<Person> AND <Customer>
SHACL:
<User> sh:constraint [ sh:and (<Person> <Customer>) ]
| ShapeNot | { | shapeExpr:shapeExpr } |
|---|
shape:Shape
The shapeExpr shape is consructed as the Shape shapes.
ShEx:
<User> @<Person> AND NOT <Customer>
SHACL:
<User> sh:constraint [ sh:and (<Person> [ sh:not <Customer> ]) ]
| ShapeRef | { | reference:shapeLabel } |
|---|
The construction of a ShapeRef is the construction of the shapeExpr for shapeLabel in the ShEx Schema's shapes map.
ShEx:
<User> @<Person> <Person> <X> AND <Y>
SHACL:
<User> sh:constraint [ sh:and (<X> <Y> ) ]
| ShapeExternal | { | /* empty */ } |
|---|
A schemas with a ShapeExternal has no translation to SHACL.
| NodeConstraint | { | nodeKind:("iri" | "bnode" | "nonliteral" | "literal")? datatype:IRI? xsFacet* values:[valueSetValue]? } |
|---|
parms:Set[Parameter]
A ShEx NodeConstraint constructs a set of SHACL Parameters.
kind:"IRI"|"blank node"|"nonliteral"|"literal"
A ShEx nodeKind translates to:
sh:IRI)sh:BlankNode)sh:IRIOrBlankNode)sh:IRI)ShEx:
<IssueShape> { ex:state [ex:Resolved, ex:Rejected] }
SHACL:
<IssueShape> sh:property [ sh:predicate ex:state; sh:in (ex:Resolved, ex:Rejected) ] .
| objectValue | = | IRI | STRING | DATATYPE_STRING | LANG_STRING ; |
|---|---|---|
| valueSetValue | = | objectValue | Stem | StemRange ; |
| Stem | { | stem:IRI } |
| StemRange | { | stem:(IRI | Wildcard) exclusions:[objectValue|Stem]? } |
| Wildcard | { | /* empty */ } |
vals:Set[RDF term]
str:RDFLiteral
A ShEx values translates as follows:
Construct a list l of RDF terms and a list ors of NodeConsraints.
For valueSetValue v in vals:
v is an objectValue, l = l+l.v is a Stem, ors = ors+NodeConstraint(Stem(v.stem)).v is a StemRange, construct a set of exclusions ex as follows:
For each objectValue or Stem t in exclusions,
t is an objectValue, ex = ex+l.t is a Stem, ors = ors+NodeConstraint(Stem(v.stem)).ors = ors+And(NodeConstraint(Stem(v.stem)), Not(Or(ex))).
A ShEx values translates to:
if ors is empty, In(l)
ShEx:
<Issue> { ex:status [ex:Unassigned ex:Assigned ex:Resolved] }
SHACL:
<Issue> [ ex:property ex:status; sh:in (ex:Unassigned ex:Assigned ex:Resolved)
otherwise, Or(In(l),Or(ors))
ShEx:
<Issue> { ex:status [ex:Unassigned ex:Assigned-by~ ex:Resolved-by~ - ex:Resolved-by-dismissal - ex:Resolved-by-dismissal-for~] }
SHACL:
<Issue> [ ex:property ex:status;
sh:shape [ sh:or (
[ sh:in (ex:Unassigned) ]
[ sh:stem ex:Assigned-by ]
[ sh:and (
[ sh:stem ex:Resolved-by~ ]
[ not [ sh:in (ex:Resolved-by-dismissal) ] ]
[ not [ sh:stem (ex:Resolved-by-dismissal-for) ] ] ) ] ) ] ]
dt:IRI
A ShEx datatype of t translates to a Datatype(t)
ShEx:
<DateShape> xsd:dateTime
SHACL:
<Dateshape> sh:datatype xsd:dateTime
| xsFacet | = | stringFacet | numericFacet ; |
|---|---|---|
| stringFacet | = | ("length"|"minlength"|"maxlength"):INTEGER | pattern:STRING ; |
ref:numeric
ref:numeric
pat:RDFLiteral, flagstr:RDFLiteral
| numericFacet | = | ("mininclusive"|"minexclusive"|"maxinclusive"|"maxexclusive"):numericLiteral |
|---|---|---|
| | | ("totaldigits"|"fractiondigits"):INTEGER ; | |
| numericLiteral | = | INTEGER | DECIMAL | DOUBLE ; |
ref:RDFLiteral
ref:RDFLiteral
ref:RDFLiteral
ref:RDFLiteral
| Shape | { | closed:BOOL? extra:[IRI]? expression:tripleExpr?]? } |
|---|
| tripleExpr | = | EachOf | SomeOf | TripleConstraint | Inclusion ; |
|---|
The construction of a Shape is a Partition with an expression of the construction of the tripleExpr and expression.
| EachOf | { | expressions:[tripleExpr] min:INTEGER? max:(INTEGER | "*")? semActs:[SemAct]? annotations:[Annotation]? } |
|---|
exprs:Set[Sexpr]
Each tripleExpr in tripleExprs is consructed as a Shape in shapes.
ShEx:
<User> { foaf:givenName . ; foaf:familyName }
SHACL:
<User> sh:partition [ sh:group (
[ sh:property foaf:givenName; sh:minCount 1; sh:maxCount 1 ]
[ sh:property foaf:familyName; sh:minCount 1; sh:maxCount 1 ]
) ]
| SomeOf | { | expressions:[tripleExpr] min:INTEGER? max:(INTEGER | "*")? semActs:[SemAct]? annotations:[Annotation]? } |
|---|
exprs:Set[Sexpr]
Each tripleExpr in tripleExprs is consructed as a Shape in shapes.
ShEx:
<User> { foaf:name . | vcard:name }
SHACL:
<User> sh:partition [ sh:choice (
[ sh:property foaf:name; sh:minCount 1; sh:maxCount 1 ]
[ sh:property vcard:name; sh:minCount 1; sh:maxCount 1 ]
) ]
| TripleConstraint | { | inverse:BOOL? negated:BOOL? predicate:IRI valueExpr:shapeExpr? min:INTEGER? max:(INTEGER | "*")? semActs:[SemAct]? annotations:[Annotation]? } |
|---|
path:SPARQLPropertyPath, parms:Set[Parameter]
| Inclusion | { | include:shapeLabel } |
|---|
The construction of a Inclusion is the construction of the shapeExpr for shapeLabel in the ShEx Schema's shapes map.
A schemas with a ShapeExternal has no translation to SHACL.
| Annotation | { | predicate:IRI object:objectValue } |
|---|
ShEx Annotations construct triples with the subject of the current expression, predicate predicate and object: object