Search code examples
sparql

SPARQL - Returning label when object is URI or string when object is Literal


I would like to get the labels (rdfs:label) of objects when the object is a URI. But I would also like to get the string values when the object is a literal string. The issue is, I do not know beforehand if the object is storing a literal or a URI, and in some cases I see a mix of both literals and URIs, like in the image attached.

enter image description here

Any suggestions on how I can return the strings, and if there's an object, return the rdfs:label?

Thanks for your help!


Solution

  • First, this problem shouldn't occur in an ideal world because a property is supposed to be either an object property or a datatype property.

    However, when dealing with low quality data where this does occur, I suggest the following workaround:

    SELECT ?x ?desc
    {
     ?x dbp:keyPeople ?y.
     {?y rdfs:label ?desc. FILTER(isIRI(?y))} UNION
     {BIND(STR(?y) AS ?desc). FILTER(!isIRI(?y))}
    }
    

    Warning

    This is not thoroughly tested. I could only verify that it works correctly on DBpedia Live, which uses Virtuoso 08.03.3319. On the default DBpedia endpoint https://dbpedia.org/sparql on Virtuoso version 07.20.3235 it seems to not work correctly. Also, you need to uncheck both "Strict checking of void variables" and "Strict checking of variable names used in multiple clauses but not logically connected to each other".