2

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?

Jacob G.
  • 28,856
  • 5
  • 62
  • 116
  • 1
    What SHACL engine did you use? I am not getting errors for the first example, either with the TopBraid SHACL API or the SHACL Playground. – Holger Knublauch Oct 30 '19 at 06:53
  • On the general topic of validating rdf:Lists, see https://www.topquadrant.com/constraints-on-rdflists-using-shacl/ – Holger Knublauch Oct 30 '19 at 06:53
  • can't reproduce it with Apache Jena 3.13.1 either – UninformedUser Oct 30 '19 at 07:01
  • 1
    @HolgerKnublauch I realized that it was failing due to a problem on my end that I'd rather not go into. You were correct that the first example **does** conform. Thank you for your help! – Jacob G. Oct 30 '19 at 14:22
  • Can someone tell me how was this solved? Do I need to use dash:ListShape to solve it as shown in the example above linked by @HolgerKnublauch? I have the same problem and am unable to solve it. – Ann Jan 10 '20 at 01:02
  • @Ann There was never actually a problem here. The example in my question should work for you! – Jacob G. Jan 10 '20 at 01:03
  • It works. But then if myList is just an object (instead of a list of objects) even then this shape works. So how do we differentiate shape between the two (object vs. list of objects)? – Ann Jan 10 '20 at 01:06
  • @Ann By "object", I assume you're referring to JSON object. With what you're saying, it's helpful to think of an "object" as an array of "objects" that only contains a single element. If an array contains a single element, it doesn't require any square brackets to surround it. – Jacob G. Jan 10 '20 at 01:10
  • in your example, by object I meant if "myList" : { "year" : "2019", "month" : "October", "day" : "29" } Would shape be the same for both cases? – Ann Jan 10 '20 at 01:19
  • 1
    @Ann Like I stated, that can be considered to be an array that contains a single element, so the square brackets aren't required. I would think validation would still be successful if you used `"myList" : [{ "year" : "2019", "month" : "October", "day" : "29" }]` – Jacob G. Jan 10 '20 at 01:21

1 Answers1

0

Yes, SHACL can validate JSON-LD containing a list of objects.

PEBCAK error caused the failure. (See comments.)

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
TallTed
  • 9,069
  • 2
  • 22
  • 37