diff --git a/index.html b/index.html index fd9fd86..4c662cc 100644 --- a/index.html +++ b/index.html @@ -1365,8 +1365,240 @@

Value Sets

+ + +
+

RDF Structures

+

+ RDF and RDFS specify some RDF structures. + This section describes how ShEx can be used to validate instances of those structures. +

+ +
+

RDF Collections

+ +

+ RDF Collections are a way of creating an ordered list composed of a chain of rdf:first and rdf:rest properties. + In the Issue example below, fail0 example violates the constraint that the schema indicates that the list may not be empty. The failU1P1 example fails because the first element is out of range. + The failP1U1 example fails because the last item is out of range. +

+
+ +
+ +
BASE <http://a.example/schema>
+PREFIX : <#>
+PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
+PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+
+<#Issue> { :affects @<#List_Product> }
+
+<#List_Product> CLOSED {
+  rdf:first @<#Product> ;
+  rdf:rest [rdf:nil] OR @<#List_Product>
+}
+
+<#Product> {
+  :number xsd:integer ;
+  :name LITERAL
+}
+
+<#User> {
+  :name LITERAL
+}
+ + +
{
+  "type": "Schema",
+  "shapes": [
+    {
+      "type": "Shape",
+      "id": "http://a.example/schema#Issue",
+      "expression": {
+        "type": "TripleConstraint",
+        "predicate": "http://a.example/schema#affects",
+        "valueExpr": "http://a.example/schema#List_Product"
+      }
+    },
+    {
+      "type": "Shape",
+      "id": "http://a.example/schema#List_Product",
+      "closed": true,
+      "expression": {
+        "type": "EachOf",
+        "expressions": [
+          {
+            "type": "TripleConstraint",
+            "predicate": "http://www.w3.org/1999/02/22-rdf-syntax-ns#first",
+            "valueExpr": "http://a.example/schema#Product"
+          },
+          {
+            "type": "TripleConstraint",
+            "predicate": "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest",
+            "valueExpr": {
+              "type": "ShapeOr",
+              "shapeExprs": [
+                {
+                  "type": "NodeConstraint",
+                  "values": [
+                    "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"
+                  ]
+                },
+                "http://a.example/schema#List_Product"
+              ]
+            }
+          }
+        ]
+      }
+    },
+    {
+      "type": "Shape",
+      "id": "http://a.example/schema#Product",
+      "expression": {
+        "type": "EachOf",
+        "expressions": [
+          {
+            "type": "TripleConstraint",
+            "predicate": "http://a.example/schema#number",
+            "valueExpr": {
+              "type": "NodeConstraint",
+              "datatype": "http://www.w3.org/2001/XMLSchema#integer"
+            }
+          },
+          {
+            "type": "TripleConstraint",
+            "predicate": "http://a.example/schema#name",
+            "valueExpr": {
+              "type": "NodeConstraint",
+              "nodeKind": "literal"
+            }
+          }
+        ]
+      }
+    },
+    {
+      "type": "Shape",
+      "id": "http://a.example/schema#User",
+      "expression": {
+        "type": "TripleConstraint",
+        "predicate": "http://a.example/schema#name",
+        "valueExpr": {
+          "type": "NodeConstraint",
+          "nodeKind": "literal"
+        }
+      }
+    }
+  ]
+}
+
BASE <http://a.example/data#>
+PREFIX : <http://a.example/schema#>
+
+<#passP1> :affects (<#Product1>) .
+<#passP1P2> :affects (<#Product1> <#Product2>) .
+
+<#fail0>    :affects () .                    
+<#failU1P1> :affects (<#User1> <#Product1>) .
+<#failP1U1> :affects (<#Product1> <#User1>) .
+
+<#Product1> :number 1 ; :name "toaster" .
+<#Product2> :number 2 ; :name "blender" .
+
+<#User1>    :name   "Alice" .
+try it
+
+
+ + + + + + + +
NodeShapeResultReason
passP1 Issuepass
passP1P2Issuepass
fail0 Issuefailschema prohibits empty lists.
failU1P1 Issuefailbad first element.
failP1U1 Issuefailbad last element.
+
+
+ +
+

Ambiguous Grammar

+ +

+ In the previous example, Products are distinct from Users in that they have a :productNumber. + Products can, however, masquerade as Users, so long as the User shape is not CLOSED. + Specifically, the Product instance (<#Product1>) meets the criteria for a User, i.e. it has a :name. + When validated as a User, the extra :productNumber is irrelevant (so long as the User shape is not CLOSED). +

+
+ +
+ +
BASE <http://a.example/schema>
+PREFIX : <#>
+PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
+PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+
+<#Issue> { :reporter @<#List_User> }
+
+<#List_User> CLOSED {
+  rdf:first @<#User> ;
+  rdf:rest [rdf:nil] OR @<#List_User>
+}
+
+<#User> /*not CLOSED*/ {
+  :name LITERAL
+}
+
+<#Product> {
+  :number xsd:integer ;
+  :name LITERAL
+}
+ + +

+              
BASE <http://a.example/data#>
+PREFIX : <http://a.example/schema#>
+
+<#passU1> :reporter (<#User1>) .
+<#passU1U2> :reporter (<#User1> <#User2>) .
+
+# Nodes that would fail if User were CLOSED
+<#failP1U1> :reporter (<#Product1> <#User1>) .
+<#failU1P1> :reporter (<#User1> <#Product1>) .
+
+<#User1> :name "Alice" .
+<#User2> :name "Alicia" .
+
+<#Product1> :number 1 ; :name   "toaster" .try it
+
+
+ + + + + + +
NodeShapeResultReason
passU1 Issuepass
passU1U2Issuepass
failP1U1 Issuepassfirst element "looks" like a User.
failU1P1 Issuepasslast element "looks" like a User.
+
+ +

+ If URLs in the data are expected to conform to some naming pattern, this can be enforced with regular expressions on the shape, e.g. +

+
+
+<#User> /User/ {
+  :name LITERAL
+}
+            
+
+
+
-

Advanced Concepts

diff --git a/local.css b/local.css index 6115ebb..a96fbe0 100644 --- a/local.css +++ b/local.css @@ -25,6 +25,14 @@ /* font-lock-function-name-face */ color: #0000ff; } + .relativeURL { + /* font-lock-function-name-face */ + color: #0000ff; + } + .relativeURL:visited { + /* font-lock-function-name-face */ + color: #0000ff; + } .keyword, .schema .keyword.object { /* font-lock-keyword-face */ color: #a020f0;