Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions shacl12-core/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5445,6 +5445,7 @@ <h4>sh:in</h4>
</div>
</aside>
</section>

<section id="RootClassConstraintComponent">
<h4>sh:rootClass</h4>
<p>
Expand Down Expand Up @@ -5529,6 +5530,124 @@ <h4>sh:rootClass</h4>
</div>
</aside>
</section>

<section id="UniqueValuesForConstraintComponent">
<h4>sh:uniqueValuesFor</h4>
<p>
<code>sh:uniqueValuesFor</code> specifies the condition that the values of one or more specified properties of a <a>value node</a>
must be unique within all <a>target</a> nodes of the current <a>shape</a>.
</p>
<p>
<span class="component-class">Constraint Component IRI</span>: <code>sh:UniqueValuesForConstraintComponent</code>
</p>

<div class="parameters">Parameters:</div>
<table class="term-table">
<thead>
<tr>
<th>Property</th>
<th>Summary and Syntax Rules</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>sh:uniqueValuesFor</code></td>
<td>
<span data-syntax-rule="uniqueValuesFor-node">An <a>IRI</a> of a property, or
a <a>SHACL list</a> where each <a>member</a> is an <a>IRI</a> of a property.</span>
</td>
</tr>
</tbody>
</table>
<div class="def def-text">
<div class="def-header">TEXTUAL DEFINITION</div>
<div class="def-text-body" data-validator="In">
Let <code>$uniqueValuesFor</code> be a <a>value</a> of <code>sh:uniqueValuesFor</code> in <a>shape</a> <code>S</code>.
Let <code>$properties</code> be the set as follows:
If <code>$uniqueValuesFor</code> is an <code>IRI</code> then <code>$properties = { uniqueValuesFor }</code>.
If <code>$uniqueValuesFor</code> is a <a>SHACL list</a>, then <code>$properties</code> is the set of the <a>members</a> of that list.
Let <code>$targetNodes</code> be the <a>target</a> nodes of <code>S</code>.
<br />
For each <a>value node</a> <code>V</code> for which there exists another <a>node</a> <code>Other</code> in <code>$targetNodes</code>
that has exactly the same <a>values</a> for all properties in <code>$properties</code> as <code>V</code>
there is a <a>validation result</a> with <code>Other</code> as <code>sh:value</code>.
No result is produced if <code>V</code> has no <a>values</a> for any of the properties in <code>$properties</code>.
</div>
</div>
<p><em>The remainder of this section is informative.</em></p>
<p>
Note that matching of literals needs to be exact, e.g. <code>"04"^^xsd:byte</code> does not match <code>"4"^^xsd:integer</code>.
</p>
<aside class="example" title="Example of sh:uniqueValuesFor on a single property">
<div class="shapes-graph">
<div class="turtle">
ex:SingleIdExampleShape
a sh:NodeShape ;
sh:targetClass ex:Record ;
sh:uniqueValuesFor ex:id ;
.
</div>
</div>
<div class="data-graph">
<div class="turtle">
ex:Record1
a ex:Record ;
ex:id "One" .

ex:UnrelatedNode
ex:id "One" .

ex:Record2
a ex:Record ;
<span class="focus-node-error">ex:id "Two"</span> .

ex:Record3
a ex:Record ;
<span class="focus-node-error">ex:id "Two"</span> .
</div>
</div>
<p>
In this example, two constraint violations will be reported, for <code>ex:Record2</code> and <code>ex:Record3</code>
because they have exactly the same values for <code>ex:id</code> and are in the <a>target</a> of the same <a>shape</a>.
</p>
<p>
However, no violation is reported for <code>ex:id "One"</code> because <code>ex:UnrelatedNode</code> is not an instance
of <code>ex:Record</code> and therefore not targeted by <code>ex:SingleIdExampleShape</code>.
</p>
</aside>
<p>
Note that the computation of the <a>target</a> nodes depends only on the definition of the shape, e.g.
the <code>sh:targetClass</code> declaration of the shape that also holds the <code>sh:uniqueValuesFor</code> constraint.
</p>
<aside class="example" title="Example of sh:uniqueValuesFor on a pair of two properties">
<div class="shapes-graph">
<div class="turtle">
ex:CombinedIdExampleShape
a sh:NodeShape ;
sh:targetClass ex:Concept ;
sh:uniqueValuesFor ( ex:notation ex:inScheme ) ;
.
</div>
</div>
<div class="data-graph">
<div class="turtle">
ex:Concept1
a ex:Concept ;
ex:notation "123" ;
ex:inScheme ex:Scheme1 .

ex:Concept2
a ex:Concept ;
ex:notation "123" ;
ex:inScheme ex:Scheme2 .
</div>
</div>
<p>
In the example above, no violations are reported because none of the focus nodes of the shape
have the same combination of the two specified properties.
</p>
</aside>
</section>
</section>
</section>

Expand Down Expand Up @@ -6078,6 +6197,7 @@ <h2>Changes between the original SHACL Core and SHACL 1.2 Core</h2>
<li>Added support for `rdf:dirLangString` to <a href="#UniqueLangConstraintComponent"></a>, see <a href="https://github.com/w3c/data-shapes/issues/737">Issue 737</a></li>
<li>Added the new constraint component <a href="#RootClassConstraintComponent"><code>sh:rootClass</code></a>, see <a href="https://github.com/w3c/data-shapes/issues/792">Issue 792</a></li>
<li>Added the new constraint component <a href="#SubsetOfConstraintComponent"><code>sh:subsetOf</code></a>, see <a href="https://github.com/w3c/data-shapes/issues/786">Issue 786</a></li>
<li>Added the new constraint component <a href="#UniqueValuesForConstraintComponent"><code>sh:uniqueValuesFor</code></a>, see <a href="https://github.com/w3c/data-shapes/issues/661">Issue 661</a></li>
</ul>
</section>
</body>
Expand Down
3 changes: 3 additions & 0 deletions shacl12-test-suite/tests/core/node/manifest.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
mf:include <pattern-001.ttl> ;
mf:include <pattern-002.ttl> ;
mf:include <uniqueMembers-001.ttl> ;
mf:include <uniqueValuesFor-001.ttl> ;
mf:include <uniqueValuesFor-002.ttl> ;
mf:include <uniqueValuesFor-003.ttl> ;
mf:include <xone-001.ttl> ;
mf:include <xone-duplicate.ttl> ;
mf:include <qualified-001.ttl> ;
Expand Down
67 changes: 67 additions & 0 deletions shacl12-test-suite/tests/core/node/uniqueValuesFor-001.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
@prefix ex: <http://example.com/ns#> .
@prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
@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 sht: <http://www.w3.org/ns/shacl-test#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:TestShape
rdf:type sh:NodeShape ;
sh:targetClass ex:TestShape ;
sh:uniqueValuesFor ex:id ;
.
ex:ValidInstance1
rdf:type ex:TestShape ;
ex:id "001" ;
.
ex:ValidInstance2
rdf:type ex:TestShape ;
ex:id "002" ;
.
ex:UnrelatedNodeThatIsNotInTarget
ex:id "002" ;
.
ex:InvalidInstance1
rdf:type ex:TestShape ;
ex:id "DUP" ;
.
ex:InvalidInstance2
rdf:type ex:TestShape ;
ex:id "DUP" ;
.
<>
rdf:type mf:Manifest ;
mf:entries (
<uniqueValuesFor-001>
) ;
.
<uniqueValuesFor-001>
rdf:type sht:Validate ;
rdfs:label "Test of sh:uniqueValuesFor at node shape 001 (single property)" ;
mf:action [
sht:dataGraph <> ;
sht:shapesGraph <> ;
] ;
mf:result [
rdf:type sh:ValidationReport ;
sh:conforms "false"^^xsd:boolean ;
sh:result [
rdf:type sh:ValidationResult ;
sh:focusNode ex:InvalidInstance1 ;
sh:resultSeverity sh:Violation ;
sh:sourceConstraintComponent sh:UniqueValuesForConstraintComponent ;
sh:sourceShape ex:TestShape ;
sh:value ex:InvalidInstance2 ;
] ;
sh:result [
rdf:type sh:ValidationResult ;
sh:focusNode ex:InvalidInstance2 ;
sh:resultSeverity sh:Violation ;
sh:sourceConstraintComponent sh:UniqueValuesForConstraintComponent ;
sh:sourceShape ex:TestShape ;
sh:value ex:InvalidInstance1 ;
] ;
] ;
mf:status sht:approved ;
.
69 changes: 69 additions & 0 deletions shacl12-test-suite/tests/core/node/uniqueValuesFor-002.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
@prefix ex: <http://example.com/ns#> .
@prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
@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 sht: <http://www.w3.org/ns/shacl-test#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:TestShape
rdf:type sh:NodeShape ;
sh:targetClass ex:TestShape ;
sh:uniqueValuesFor ( skos:notation skos:inScheme ) ;
.
ex:ValidInstance1
rdf:type ex:TestShape ;
skos:notation "A1" ;
skos:inScheme ex:Scheme1 ;
.
ex:ValidInstance2
rdf:type ex:TestShape ;
skos:notation "A2" ;
skos:inScheme ex:Scheme1 ;
.
ex:InvalidInstance1
rdf:type ex:TestShape ;
skos:notation "A1" ;
skos:inScheme ex:Scheme2 ;
.
ex:InvalidInstance2
rdf:type ex:TestShape ;
skos:notation "A1" ;
skos:inScheme ex:Scheme2 ;
.
<>
rdf:type mf:Manifest ;
mf:entries (
<uniqueValuesFor-002>
) ;
.
<uniqueValuesFor-002>
rdf:type sht:Validate ;
rdfs:label "Test of sh:uniqueValuesFor at node shape 002 (composite key)" ;
mf:action [
sht:dataGraph <> ;
sht:shapesGraph <> ;
] ;
mf:result [
rdf:type sh:ValidationReport ;
sh:conforms "false"^^xsd:boolean ;
sh:result [
rdf:type sh:ValidationResult ;
sh:focusNode ex:InvalidInstance1 ;
sh:resultSeverity sh:Violation ;
sh:sourceConstraintComponent sh:UniqueValuesForConstraintComponent ;
sh:sourceShape ex:TestShape ;
sh:value ex:InvalidInstance2 ;
] ;
sh:result [
rdf:type sh:ValidationResult ;
sh:focusNode ex:InvalidInstance2 ;
sh:resultSeverity sh:Violation ;
sh:sourceConstraintComponent sh:UniqueValuesForConstraintComponent ;
sh:sourceShape ex:TestShape ;
sh:value ex:InvalidInstance1 ;
] ;
] ;
mf:status sht:approved ;
.
60 changes: 60 additions & 0 deletions shacl12-test-suite/tests/core/node/uniqueValuesFor-003.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
@prefix ex: <http://example.com/ns#> .
@prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
@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 sht: <http://www.w3.org/ns/shacl-test#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:TestShape
rdf:type sh:NodeShape ;
sh:targetSubjectsOf ex:id ;
sh:uniqueValuesFor ex:id ;
.
ex:ValidInstance1
ex:id "001" ;
.
ex:ValidInstance2
ex:id "002" ;
.
ex:InvalidInstance1
ex:id "DUP" ;
.
ex:InvalidInstance2
ex:id "DUP" ;
.
<>
rdf:type mf:Manifest ;
mf:entries (
<uniqueValuesFor-003>
) ;
.
<uniqueValuesFor-003>
rdf:type sht:Validate ;
rdfs:label "Test of sh:uniqueValuesFor at node shape 003 (targetSubjectsOf, global uniqueness)" ;
mf:action [
sht:dataGraph <> ;
sht:shapesGraph <> ;
] ;
mf:result [
rdf:type sh:ValidationReport ;
sh:conforms "false"^^xsd:boolean ;
sh:result [
rdf:type sh:ValidationResult ;
sh:focusNode ex:InvalidInstance1 ;
sh:resultSeverity sh:Violation ;
sh:sourceConstraintComponent sh:UniqueValuesForConstraintComponent ;
sh:sourceShape ex:TestShape ;
sh:value ex:InvalidInstance2 ;
] ;
sh:result [
rdf:type sh:ValidationResult ;
sh:focusNode ex:InvalidInstance2 ;
sh:resultSeverity sh:Violation ;
sh:sourceConstraintComponent sh:UniqueValuesForConstraintComponent ;
sh:sourceShape ex:TestShape ;
sh:value ex:InvalidInstance1 ;
] ;
] ;
mf:status sht:approved ;
.
20 changes: 20 additions & 0 deletions shacl12-vocabularies/shacl.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -1359,6 +1359,26 @@ sh:uniqueLang
rdfs:isDefinedBy sh: .


sh:UniqueValuesForConstraintComponent
a sh:ConstraintComponent ;
rdfs:label "Unique-values-for constraint component"@en ;
rdfs:comment "A constraint component that can be used to ensure that no two nodes targeted by the same shape have the same combination of values for a given set of properties."@en ;
sh:parameter sh:UniqueValuesForConstraintComponent-uniqueValuesFor ;
rdfs:isDefinedBy sh: .

sh:UniqueValuesForConstraintComponent-uniqueValuesFor
a sh:Parameter ;
sh:path sh:uniqueValuesFor ;
sh:nodeKind sh:BlankNodeOrIRI ;
rdfs:isDefinedBy sh: .

sh:uniqueValuesFor
a rdf:Property ;
rdfs:label "unique values for"@en ;
rdfs:comment "Specifies one or more properties (as a URI or rdf:List of URIs) for which no two nodes targeted by the same shape may have the same combination of values."@en ;
rdfs:isDefinedBy sh: .


sh:XoneConstraintComponent
a sh:ConstraintComponent ;
rdfs:label "Exactly one constraint component"@en ;
Expand Down
Loading