Search code examples
sparqlrdfsemantic-web

Retrieve country code from RDF source recieved via Sparql query


I have the following query on this endpoint https://data.bnf.fr/sparql/ :

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdagroup2elements: <http://rdvocab.info/ElementsGr2/>
PREFIX bio: <http://vocab.org/bio/0.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT distinct ?name ?nationality
WHERE {
?oeuvre dcterms:creator ?author.
?author foaf:name ?name.
?author rdagroup2elements:countryAssociatedWithThePerson ?nationality.
}
ORDER BY DESC (?mort) LIMIT 100

Which returns a list of authors with a nationality field that is itself another RDF source : enter image description here

So, for the first author Jean Martin, I get this link to another RDF source, in the case for the country France : http://id.loc.gov/vocabulary/countries/fr

How could I modify the query to receive the country code (or country name, if not possible) instead of this link, in this case FR (or France)?


Solution

  • An alternative to extracting the country code from the URI, using "the Linked Data way":

    The default graph of the endpoint https://data.bnf.fr/sparql/ doesn’t provide any data about the entities under the namespace http://id.loc.gov/vocabulary/countries/, but it provides entities under the namespace http://data.bnf.fr/vocabulary/countrycodes/, which have an owl:sameAs link to them.

    For example:

    <http://data.bnf.fr/vocabulary/countrycodes/fr> <http://www.w3.org/2002/07/owl#sameAs> <http://id.loc.gov/vocabulary/countries/fr> .
    

    And these http://data.bnf.fr/vocabulary/countrycodes/ entities refer to the country code with skos:notation, and to the country name with skos:prefLabel (language-tagged).

    For these cases, getting the country code would be possible with this property path:

    ?author rdagroup2elements:countryAssociatedWithThePerson/^owl:sameAs/skos:notation ?countryCode .
    

    Unfortunately, only some rdagroup2elements:countryAssociatedWithThePerson values are under the http://id.loc.gov/vocabulary/countries/ namespace, while other values are under the http://data.bnf.fr/vocabulary/countrycodes/ namespace directly.

    To find both cases, you could use UNION:

    { ?author rdagroup2elements:countryAssociatedWithThePerson/^owl:sameAs/skos:notation ?countryCode . } 
    UNION 
    { ?author rdagroup2elements:countryAssociatedWithThePerson/skos:notation ?countryCode . }
    

    The full query:

    PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX rdagroup2elements: <http://rdvocab.info/ElementsGr2/>
    PREFIX bio: <http://vocab.org/bio/0.1/>
    PREFIX dcterms: <http://purl.org/dc/terms/>
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
        
    SELECT DISTINCT ?name ?countryCode
    WHERE {
      ?oeuvre dcterms:creator ?author.
      ?author foaf:name ?name.
      
      { ?author rdagroup2elements:countryAssociatedWithThePerson/^owl:sameAs/skos:notation ?countryCode . } 
      UNION 
      { ?author rdagroup2elements:countryAssociatedWithThePerson/skos:notation ?countryCode . }
      
    }
    LIMIT 100
    

    (In case you didn’t intend it: Your query treats different persons with the same name and country as one entry. To prevent this, you could output the person’s URI.)