Allow sh:name and sh:description on node shapes - #1250
Conversation
3574fc1 to
6833933
Compare
9f78a52 to
10eec9b
Compare
- Broadens the domain of sh:name and sh:description to sh:Shape - Clears up confusion between rdfs:label and sh:name - Broadens prose about sh:name and sh:description to include node shapes - Added basic example containing sh:name and rdfs:label - Added example of sh:name in case of different targeting mechanism than sh:targetClass
10eec9b to
bc8a4b4
Compare
| <p> | ||
| If present, tools should prefer such locally specified labels | ||
| over globally specified labels at the <code>rdf:Property</code> itself. | ||
| over globally specified labels at the <code>rdf:Property</code> or the <code>rdfs:Class</code> itself. |
There was a problem hiding this comment.
I think it would probably be best to not suggest that sh:name overrides the label of the class, but rather is a name that could be applied to the set of targets of the shape.
As mentioned in more detail in #1234, If the intent is to actually render resources by class, then it likely makes the most sense to continue to use the label of the class. But if the intent is instead to render resources targeted by a node shape (which in some cases may just happen to be a single sh:targetClass), then it makes sense to look at the sh:name of the node shape.
Along those lines, it may be useful to use an example similar to the following to make it clear that sh:name is not a label override for a class:
ex:SocialNetworkParticipantShape
a sh:NodeShape ;
sh:targetClass :Person ;
sh:targetSubjectsOf foaf:knows ;
sh:targetObjectsOf foaf:knows ;
# The following are about the shape itself
rdfs:label "Social Network Participant Shape" ;
rdfs:comment "The constraints to apply to all participants in a social network." ;
# The following are about the set of targets of this shape
sh:name "Social Network Participant" ;
sh:description "A participant in a social network." ;
.That's at least my opinion- I don't know if anyone else from the UI group (@edmondchuc, @bergos, @smessie) has an opinion on this.
There was a problem hiding this comment.
yes generally I agree, however it is also the cases that the problem space is relatively small.
I guess its a hierarchy of best matches, to less good matches but still mostly fitting and sometimes real misses.
The cases where rdfs:label can not be used as a fallback for a missing sh:name are small.
It boils down to targets that do not resemble a class anymore.
I guess it would be good to discuss the other ways of targeting apart from sh:targetClass and see if the label matching algorithm is still good, or that we should narrow it to only shapes with targetClass or implicit target classes.
There was a problem hiding this comment.
I think the example provided by @mgberg is very helpful here and should be included.
On overriding, yes I think it should be consistent: As sh:name overrides the rdfs:label of an rdf:Property, so should sh:name override the rdfs:label of a Class. It only really affects the forms, i.e. mainly SHACL UI.
There was a problem hiding this comment.
I'm still not sure we should say "sh:name overrides the rdfs:label of a Class". There is in general a many-to-many relationship between node shapes and classes (and beyond that, since shapes don't have to target classes).
Suppose we decide to also allow :Organizations to be social network participants:
ex:SocialNetworkParticipantShape
a sh:NodeShape ;
sh:targetClass :Person ;
sh:targetClass :Organization ;
sh:targetSubjectsOf :follows ;
sh:targetObjectsOf :follows ;
# The following are about the shape itself
rdfs:label "Social Network Participant Shape" ;
rdfs:comment "The constraints to apply to all participants in a social network." ;
# The following are about the set of targets of this shape
sh:name "Social Network Participant" ;
sh:description "A participant in a social network." ;
.
If we say that "sh:name overrides the rdfs:label of a Class", then the labels for both :Person and :Organization classes would be "Social Network Participant", and I don't think that would be desired if you were looking at resources on a class-by-class basis.
Furthermore, suppose we then add the following shapes to the above:
ex:PersonShape
a sh:NodeShape ;
sh:targetClass :Person ;
# The following are about the shape itself
rdfs:label "Person Shape" ;
rdfs:comment "The constraints to apply to all people." ;
# The following are about the set of targets of this shape
sh:name "Person" ;
sh:description "A person." ;
.
ex:OrganizationShape
a sh:NodeShape ;
sh:targetClass :Organization ;
# The following are about the shape itself
rdfs:label "Organization Shape" ;
rdfs:comment "The constraints to apply to all organizations." ;
# The following are about the set of targets of this shape
sh:name "Organization" ;
sh:description "An organization." ;
.
Now, each class has two sh:names to pick from. How would you know which sh:name would you use?
I believe both issues are sidestepped if sh:name on a node shape labels only the set of targets of that shape and is not treated as a class-level override. Anything targeted by ex:SocialNetworkParticipantShape is a "Social Network Participant" regardless of its class, and :Person keeps its own rdfs:label.
This is also somewhat consistent with how sh:name already works on property shapes, in the sense that it doesn't globally replace an rdf:Property's name but only relabels it in a given context. That allows, for example, the property dcterms:identifier to be displayed with different user-friendly labels/descriptions per class. The node shape case is the same idea: the label applies in the context of a target set, not in the context of class instances.
There was a problem hiding this comment.
@mgberg thanks for the in depth comment. I think I might understand your perspective. Maybe it works best to check by scenarios:
Showing a list of buttons to create new things, eg. "Create a new person"
If I understand you correct the following is problematic:
select ?class ?label where {
{
# Class based targets
?s a sh:NodeShape ;
sh:targetClass ?class ;
sh:name ?label ;
} union {
# Implicit class targets
?class a sh:NodeShape ;
a rdfs:Class ;
sh:name ?label ;
}
}(lets not deal with multilingual labels in these examples)
This might give incorrect labels because:
- We do not know how many shapes directly target ex:Person
- When there are multiple shapes, there is no clear way to determine the canonical shape
- The shapes might target ex:Person but for example also ex:Product via another sh:targetClass. Multiple targeting ways may exist in 1 node shape.
Observations
- the more targeting ways inside a shape, a higher change it does not exactly represent a class
- the more constraints added, a higher chance a nodeShape does not exactly represent a class
If we could mark a shape as the canonical shape for a class, we would have less of this problem.
Maybe something like sh:CanonicalNodeShape?
One could make the argument that when there is only one shape in the shapes graph that targets a certain class via sh:targetClass and that is the only targeting in the shape, that it is maybe closer to representing the class fully.
Possible solution for this particular context:
select ?class ?label where {
{
?s a sh:NodeShape ;
sh:targetClass ?class ;
?class rdfs:label ?label ;
} union {
?class a sh:NodeShape ;
a rdfs:Class ;
?class rdfs:label ?label ;
}
}Observation: sh:name can be used as long as start from the shape, but not when we start from classes and go through sh:targetClass to the shapes. Then there is more chance sh:name is incorrect.
Show a list of target nodes of a shape
- The shape can be followed to get target nodes
- sh:name can be used to caption the list
No problems here as sh:name labels the target nodes.
Showing "Edit Person John Doe"
- This is fine, a SHACL renderer has the interface:
- data graph
- shapes graph
- focus node (ex:JohnDoe)
- nodeShape (ex:PersonShape)
- As we have one nodeShape, we can just get its sh:name
Summary:
It is incorrect to assume that a node shape with sh:targetClass {class} will have an sh:name that labels {class}, it can be a very narrow subset of {class} that it labels.
When starting from the shape sh:name always labels the target nodes correct.
Observation and slight sidetrack:
sh:name also labels a property path, it might also be incorrect to assume it overrides the property label from the ontology, it labels the property contextually:
Example:
sh:property [
sh:name "Ingredient" ;
sh:path [
sh:alternativePath (
schema:value schema:unitCode schema:name
)
] ;
] ;In this particular example the property was about Ingredients:
schema:value 2
schema:unitCode ex:Tablespoon
schema:name Mustard
And sh:alternativePath was used to mean more like sh:concatenatedPaths
In that case it can create the label: "2 Tablespoon Mustard".
Not sure if we should go that route. But basically a property path ends with properties but it is not said that the rdfs:label's of the property path leaves always represents whatever is captured.
Proposal:
- Remove any text that hints at override about sh:name and sh:description in SHACL core
- Write a guidance in SHACL UI, where we explain how to show a list of classes that can be created with the shapes from the shapes graph.
| <p> | ||
| If present, tools should prefer such locally specified labels | ||
| over globally specified labels at the <code>rdf:Property</code> itself. | ||
| over globally specified labels at the <code>rdf:Property</code> or the <code>rdfs:Class</code> itself. |
There was a problem hiding this comment.
I think the example provided by @mgberg is very helpful here and should be included.
On overriding, yes I think it should be consistent: As sh:name overrides the rdfs:label of an rdf:Property, so should sh:name override the rdfs:label of a Class. It only really affects the forms, i.e. mainly SHACL UI.
robert-david
left a comment
There was a problem hiding this comment.
I find the different semantics for node shapes and property shapes highly confusing. I expect users to just use it as a label if the purpose is not simple and clearly defined.
| to provide human-readable labels: | ||
| </p> | ||
| <ul> | ||
| <li>For property shapes, it is the label of the property path in the target where it appears.</li> |
There was a problem hiding this comment.
what does '.. where it appears.' mean? Is is 'from the focus nodes'?
|
|
||
| <p class="note"> | ||
| <code>sh:name</code> and <code>rdfs:label</code> are complementary. | ||
| <code>rdfs:label</code> specifies a label for the shape. <code>sh:name</code> does not. |
There was a problem hiding this comment.
'... does not.' is an insufficient definition. Maybe '... is not indented to describe the shape, but ...'
| to provide descriptions: | ||
| </p> | ||
| <ul> | ||
| <li>For property shapes, it is the description of the property path in the given context.</li> |
There was a problem hiding this comment.
It is highly confusing to have a property that changes semantics depending on where it is used. Why does sh:name for a property shape not describe the targets, but something else?
I strongly recommend to streamline this in some way. If it does not define a clear purpose, users will just use it as a label.
| rdfs:label "description"@en ; | ||
| rdfs:comment "Human-readable descriptions for the property in the context of the surrounding shape."@en ; | ||
| rdfs:domain sh:PropertyShape ; | ||
| rdfs:comment "Human-readable descriptions for the property path (for property shapes) or the target nodes (for node shapes). Not to be used as description of the shape itself."@en ; |
There was a problem hiding this comment.
Same here for unclear purpose. Generally i can put anything in a description.
| rdfs:label "name"@en ; | ||
| rdfs:comment "Human-readable labels for the property in the context of the surrounding shape."@en ; | ||
| rdfs:domain sh:PropertyShape ; | ||
| rdfs:comment "Human-readable labels for the property path (for property shapes) or the target nodes (for node shapes). Not to be used as labels for the shape itself."@en ; |
There was a problem hiding this comment.
We can even say that sh:name is a name for a shape. For property shapes, the path is the main defining element, so this would fit well. For node shapes, it describes (or summarises) the constraints, which is somehow describing what the target nodes need to have in common.
Anyways, sh:name should have some common ground on node shapes and property shapes.
|
@robert-david I tried to process your feedback, does this make it clearer for you? Are things you would like to tweak further? |
| <p class="note"> | ||
| <code>sh:name</code> and <code>rdfs:label</code> are complementary. | ||
| <code>rdfs:label</code> names the shape resource itself. | ||
| <code>sh:name</code> is not intended to name the shape resource, but rather | ||
| the shape's defining characteristic, as described above. | ||
| </p> |
There was a problem hiding this comment.
Might it be valuable to add an additional sentence here explicitly saying that sh:description follows a similar pattern?
| <p> | ||
| If present, tools should prefer such locally specified labels | ||
| over globally specified labels at the <code>rdf:Property</code> itself. | ||
| over globally specified labels at the <code>rdf:Property</code> or the <code>rdfs:Class</code> itself. |
There was a problem hiding this comment.
I'm still not sure we should say "sh:name overrides the rdfs:label of a Class". There is in general a many-to-many relationship between node shapes and classes (and beyond that, since shapes don't have to target classes).
Suppose we decide to also allow :Organizations to be social network participants:
ex:SocialNetworkParticipantShape
a sh:NodeShape ;
sh:targetClass :Person ;
sh:targetClass :Organization ;
sh:targetSubjectsOf :follows ;
sh:targetObjectsOf :follows ;
# The following are about the shape itself
rdfs:label "Social Network Participant Shape" ;
rdfs:comment "The constraints to apply to all participants in a social network." ;
# The following are about the set of targets of this shape
sh:name "Social Network Participant" ;
sh:description "A participant in a social network." ;
.
If we say that "sh:name overrides the rdfs:label of a Class", then the labels for both :Person and :Organization classes would be "Social Network Participant", and I don't think that would be desired if you were looking at resources on a class-by-class basis.
Furthermore, suppose we then add the following shapes to the above:
ex:PersonShape
a sh:NodeShape ;
sh:targetClass :Person ;
# The following are about the shape itself
rdfs:label "Person Shape" ;
rdfs:comment "The constraints to apply to all people." ;
# The following are about the set of targets of this shape
sh:name "Person" ;
sh:description "A person." ;
.
ex:OrganizationShape
a sh:NodeShape ;
sh:targetClass :Organization ;
# The following are about the shape itself
rdfs:label "Organization Shape" ;
rdfs:comment "The constraints to apply to all organizations." ;
# The following are about the set of targets of this shape
sh:name "Organization" ;
sh:description "An organization." ;
.
Now, each class has two sh:names to pick from. How would you know which sh:name would you use?
I believe both issues are sidestepped if sh:name on a node shape labels only the set of targets of that shape and is not treated as a class-level override. Anything targeted by ex:SocialNetworkParticipantShape is a "Social Network Participant" regardless of its class, and :Person keeps its own rdfs:label.
This is also somewhat consistent with how sh:name already works on property shapes, in the sense that it doesn't globally replace an rdf:Property's name but only relabels it in a given context. That allows, for example, the property dcterms:identifier to be displayed with different user-friendly labels/descriptions per class. The node shape case is the same idea: the label applies in the context of a target set, not in the context of class instances.
Co-authored-by: Matt Goldberg <59745812+mgberg@users.noreply.github.com>
Closes #1234