sparqlgraphdbshacl

Make a UNION return a single result in SPARQL


I am trying to query for the sh:description of a property shape, and if there is none, I want to follow the path to a property and get the rdfs:comment (Also for sh:name and rdfs:label). My data looks like the following:

ex:File
  a owl:Class ;
  a sh:NodeShape ;
  sh:property ex:File-name ;

ex:File-name
  a sh:PropertyShape ;
  sh:path ex:filename ;
  sh:datatype xsd:string ;
  sh:description "The name of the file" ;
  sh:maxCount 1 ;

ex:filename
  a rdf:Property ;
  rdfs:label "Filename" ;
  rdfs:comment "The file name" ;
.

I have the query below, but it returns two results. How can I modify it to only return a single result (preferring sh:description over rdfs:comment)?

PREFIX : <http://www.example.org/#>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?propertyShape ?property ?name ?description where {
    :File sh:property ?propertyShape .
    ?propertyShape sh:path ?property .
    { ?propertyShape sh:name ?name } UNION { ?property rdfs:label ?name } .
    { ?propertyShape sh:description ?description } UNION { ?property rdfs:comment ?description } .

The above returns something like this:

propertyShape property name description
:File-name ex:filename "Filename" "The name of the file"
:File-name ex:filename "Filename" "The file name"

I would like for it to return something like:

propertyShape property name description
:File-name ex:filename "Filename" "The name of the file"

Solution

  • You should be able to use a sequence of OPTIONAL blocks to do this:

    SELECT ?propertyShape ?property ?name ?description WHERE {
        :File sh:property ?propertyShape .
        ?propertyShape sh:path ?property .
    
        OPTIONAL { ?propertyShape sh:name ?name }
        OPTIONAL { ?property rdfs:label ?name }
    
        OPTIONAL { ?propertyShape sh:description ?description }
        OPTIONAL { ?property rdfs:comment ?description }
    }
    

    You'll still have to think about cases where there are multiple names/descriptions per property (this isn't guaranteed to return just a single result), but it should give you the "preferring sh:description over rdfs:comment" behavior.