-
Notifications
You must be signed in to change notification settings - Fork 2
Use case: Ordered lists as an expected data format #18
Comments
None of the work-arounds are perfect but it remains an important problem. rdf:List is a terrible but necessary solution from the last century. We have introduced a property dash:index that can be used together with reification/rdf-star. The benefit is that the values remain "normal" triples that can be accessed with set-based semantics, yet can also be queried in order if needed. Properties are marked with dash:indexed true, and constraints check that all indices from 0..N are present. Pain points include the cost if inserts and look-ups still require O(n). |
@HolgerKnublauch I could not find documentation about dash:index only this part in the ontology. dash:IndexedConstraintComponent
a sh:ConstraintComponent ;
rdfs:comment "A constraint component that can be used to mark property shapes to be indexed, meaning that each of its value nodes must carry a dash:index from 0 to N." ;
rdfs:label "Indexed constraint component" ;
sh:parameter dash:IndexedConstraintComponent-indexed ;
.
dash:IndexedConstraintComponent-indexed
a sh:Parameter ;
sh:path dash:indexed ;
dash:reifiableBy dash:ConstraintReificationShape ;
sh:datatype xsd:boolean ;
sh:description "True to activate indexing for this property." ;
sh:maxCount 1 ;
sh:name "indexed" ;
. Could you elaborate what reification/rdf-star would do? |
Assuming you have 3 children ordered by date of birth, I believe in the current RDF-star syntax draft it would look like
|
In our model, we went for a slightly different approach. For example when defining the <PropertyShape/languageIn>
a sh:PropertyShape ;
sh:path sh:languageIn ;
hanami:listOf [
sh:datatype xsd:string ;
] ;
. And when going through validation, this <PropertyShape/languageIn>
a sh:PropertyShape ;
sh:path sh:languageIn ;
sh:nodeKind sh:BlankNodeOrIRI ; # this is new
sh:node <GeneratedUri/1> ; # this is new
hanami:listOf [ # ignored by validation engine, we leave it here
sh:datatype xsd:string ;
] ;
.
<GeneratedUri/1>
a sh:NodeShape ;
sh:property [
sh:path [ sh:zeroOrMorePath rdf:rest ] ;
sh:hasValue rdf:nil ;
sh:node <GeneratedUri/2> ;
]
.
<GeneratedUri/2>
a sh:NodeShape ;
sh:or (
[
sh:hasValue rdf:nil;
sh:property [ sh:maxCount 0 ;
sh:path rdf:rest
] ;
sh:property [ sh:maxCount 0 ;
sh:path rdf:first
]
]
[
sh:not [sh:hasValue rdf:nil];
sh:property [
sh:path rdf:first ;
sh:maxCount 1 ;
sh:minCount 1;
sh:datatype xsd:string ; # the content of `hanami:listOf` is copied here
] ;
sh:property [
sh:path rdf:rest ;
sh:maxCount 1 ;
sh:minCount 1 ;
]
]
)
. So that it can be processed by vanilla SHACL validators. We also considered using something like <TitlePropertyShape>
a sh:PropertyShape ;
sh:path ex:title ;
sh:datatype rdf:langString ;
sh:languageIn (en fr) ;
. and as <PropertyShape/languageIn>
a sh:PropertyShape ;
sh:path sh:languageIn ;
sh:datatype xsd:string ;
OUR_NAMESPACE:isOrderedList true ;
. And we pass those to a validation engine, it will most likely say that Also this solution works nicely for even more complex scenarios (at least in our use cases 😛), like so <PropertyShape/or>
a sh:PropertyShape ;
sh:path sh:or ;
hanami:listOf [
sh:nodeKind sh:BlankNodeOrIRI ;
sh:or (
[
sh:class sh:PropertyShape ;
]
[
sh:node <PropertyShape> ;
]
) ;
] ;
. |
@WilliamChelman that is a nice way. The preprocessing is an elegant workaround. |
What I see missing from this discussion is the potential need to cater for viewers and editors, as well as validation.
The proposed I think I like the sh:property [
sh:name "Author reference"@en ;
hanami:listOf [ sh:path schema:author ] ;
] The above would instruct a builder to render an editing UI which sets an RDF List to |
We could define the shape for lists in our namespace. Then, we would have fixed IRI that can be used to identify lists. UI components can just ignore the content of the shape. Validators don't need to change the logic. It just requires an |
To identify that a property has rdf:Lists as values, we use
see https://datashapes.org/dash.html#ListShape With that stable URI, widgets can more easily identify lists than relying on parsing rdf:rest etc. |
I propose we copy the |
|
Should be easy to define a constraint component with a constraint such as dash:listMemberClass and dash:listMemberDatatype or dash:listMemberType |
Other constraints can be defined with the path In the last call, I had the idea that we could also define an IRI as the root of the list with the fixed path. But I missed that this would lead to a named node object value, which will be directly interpreted as path. ex:TrafficLightShape
a sh:NodeShape ;
sh:targetClass ex:TrafficLight ;
sh:property [
sh:path ex:colors ;
sh:node dash:ListShape ;
sh:property [
sh:path ( [ sh:zeroOrMorePath rdf:rest ] rdf:first ) ;
sh:datatype xsd:string ;
sh:minLength 1 ;
sh:minCount 2 ;
sh:maxCount 3 ;
]
] . |
We talked in the meeting on the 23th of August about ordered lists:
It is painful to implement ordered lists at the moment. But they give a great aspect of the data; the order. Inside my form renderer I have added a way to sort ordered lists but it was quite painful.
sh:property [ sh:name "Author reference"@en ; sh:path ( schema:author [ sh:zeroOrMorePath rdf:rest ] rdf:first ) ; ]
It would be great if we could have something like this instead:
In my form renderer I did a similar abstraction. When I detect an sh:path that specifies an ordered list for rendering the form I replace it to a normal sh:path and send the fact that is should be an ordered list to dash:editor implementation. I would be nicer to do this in the SHACL.
Questions:
References
The text was updated successfully, but these errors were encountered: