I'm looking to validate the following JSON-LD using SHACL:
{
"@context" : {
"day" : {
"@id" : "test:day"
},
"month" : {
"@id" : "test:month"
},
"myList" : {
"@id" : "test:myList"
},
"year" : {
"@id" : "test:year"
},
"schema" : "http://schema.org/",
"rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"xsd" : "http://www.w3.org/2001/XMLSchema#",
"test" : "http://www.test.com/ns#"
},
"@graph" : [ {
"@id" : "test:MyNode",
"@type" : "test:MyTargetClass",
"myList" : [
{
"year" : "2019",
"month" : "October",
"day" : "29"
},
{
"year" : "2018",
"month" : "January",
"day" : "17"
}
]
} ]
}
In the above example, myList
is a list of objects that must contain at least one element, each of which must contain all three fields: year
, month
, and day
. The following TTL is being used to validate it:
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix test: <http://www.test.com/ns#> .
test:MyListShape
a sh:NodeShape ;
sh:closed true ;
sh:ignoredProperties ( rdf:type ) ;
sh:property [
sh:path test:year ;
sh:datatype xsd:string ;
sh:minCount 1 ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path test:month ;
sh:datatype xsd:string ;
sh:minCount 1 ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path test:day ;
sh:datatype xsd:string ;
sh:minCount 1 ;
sh:maxCount 1 ;
] .
test:MyShape
a sh:NodeShape ;
sh:closed true ;
sh:ignoredProperties ( rdf:type ) ;
sh:targetClass test:MyTargetClass ;
sh:property [
sh:path test:myList ;
sh:node test:MyListShape ;
sh:minCount 1 ;
] .
Attempting to validate the JSON-LD returns a response containing the following snippet, stating why the data does not conform:
{
"@id" : "_:b3",
"@type" : "http://www.w3.org/ns/shacl#ValidationResult",
"focusNode" : "test:MyNode",
"resultMessage" : "Property may only have 1 value, but found 2",
"resultPath" : "test:myList",
"resultSeverity" : "http://www.w3.org/ns/shacl#Violation",
"sourceConstraintComponent" : "http://www.w3.org/ns/shacl#MaxCountConstraintComponent",
"sourceShape" : "_:b4"
}
Why must the test:myList
property have only 1 value even though I didn't specify a sh:maxCount
?
I've also tried changing myList
in the @context
to the following:
"myList" : {
"@id" : "test:myList",
"@container" : "@list"
}
However, this also does not conform, and returns a response containing the following snippet:
{
"@id" : "_:b0",
"@type" : "http://www.w3.org/ns/shacl#ValidationResult",
"focusNode" : "test:MyNode",
"resultMessage" : "Value does not have shape test:MyListShape",
"resultPath" : "test:myList",
"resultSeverity" : "http://www.w3.org/ns/shacl#Violation",
"sourceConstraintComponent" : "http://www.w3.org/ns/shacl#NodeConstraintComponent",
"sourceShape" : "_:b2",
"value" : "_:b1"
}
An alternative solution that I've encountered is to store myList
in a separate node in the @graph
, but this isn't ideal for my use-case:
{
"@id" : "test:myListNode",
"@type" : "test:myListNode",
"year" : [ "2019", "2018" ],
"month" : [ "October", "January" ],
"day" : [ "29", "17" ]
}
Therefore, is it possible to use SHACL to validate JSON-LD that contains a list of objects without having to use this alternative solution?