1

I'm trying to query data from dbpedia by a country's name. I want it to find it whether there is a resource for that country or via its existence in wikiPageRedirects. Here is a working version:

PREFIX res: <http://dbpedia.org/resource/>
PREFIX ont: <http://dbpedia.org/ontology/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?country ?capital ?label 
WHERE {
    { res:Dominion_of_Canada ont:capital ?capital .
    ?capital rdfs:label ?label }
UNION
    { res:Dominion_of_Canada ont:wikiPageRedirects ?country .
    ?country ont:capital ?capital .
    ?capital rdfs:label ?label }

FILTER (lang(?label) = "en") 
} 

I'd like (if possible), to factor out the ?country. Is it possible to assign a resource to a variable such that the SPARQL query looks like the following?

SELECT ?country ?capital ?label
WHERE {
{ ?country EXISTS res:Dominion_of_Canada } # to get the idea across
UNION
{ res:Dominion_of_Canada ont:wikiPageRedirects ?country }

?country ont:capital ?capital .
?capital rdfs:label ?label .
FILTER (lang(?label) = "en")
}

As ever, speed is important, too. If the resource exists, then it'd be better if it skipped searching on wikiPageRedirects.

Bonjiro
  • 335
  • 2
  • 7
  • Does the answer to http://stackoverflow.com/questions/23871225/retrieving-dbpedia-owltype-value-of-resource-with-dbpedia-owlwikipageredirect help? – Joshua Taylor Jul 06 '15 at 01:50
  • Thanks, Joshua. That part of the query is already working. I added some more details to the main question above. – Bonjiro Jul 16 '15 at 13:45
  • I don't see a query there..., but it's usually easier to post code as updates to questions. – Joshua Taylor Jul 16 '15 at 13:47
  • *"I'd like it to use res:France as the variable ?country if that resource exists."* The part about "if that resource exists" isn't quite well defined. the URI `res:France` exists, it's just a constant value, just like a number exists, or a string exists. I think you mean, though (and please correct me if I misunderstand), that you want to use res:France if it has the properties you're looking for, but otherwise, use a page that res:France redirects to. I think that the question I originally linked to may help there. – Joshua Taylor Jul 16 '15 at 13:50
  • Heh, you responded quickly! My edits are now finished. I hope that's more clear. I'm not concerned about the existence of any qualities at this point - just finding the actual dbpedia resource I'm looking for. The above query works, but I'm wondering if I can factor out the ?capital and ?label lines in this way. – Bonjiro Jul 16 '15 at 14:07
  • Have a look at [my answer](http://stackoverflow.com/a/31456508/1281433). – Joshua Taylor Jul 16 '15 at 14:07

2 Answers2

2

Checking whether a resource "exists" or not is a bit vague, since IRIs are just constant data. The question is really whether DBpedia contains any triples about a particular resource. In your case, you're wanting to know whether it it redirects to anything else, or if it has properties of its own. A property path of the form dbpedia:France dbpedia-owl:wikiPageRedirects* ?country is really probably the best way to do that. If there are no redirect links, then ?country is dbpedia:France, and if there are, then ?country is the value of the redirects. The only way to "check" is to look for those triples. I think that means you will end up with something like this (similar to what's shown in my answer to another question involving redirects):

select ?country ?anthem ?author {
  #-- The only way to really "check" that the resource 
  #-- "exists" and is not a redirect, is by checking 
  #-- whether it has any redirect links.  If it doesn't,
  #-- then ?country is dbpedia-owl:France, like you want
  #-- and if it does, then then you want to follow them.
  dbpedia:France dbpedia-owl:wikiPageRedirects* ?country .

  #-- I'm using anthem and author here because 
  #-- it doesn't look like there was reliable information
  #-- about the capital.
  ?country dbpedia-owl:anthem ?anthem .                  
  ?anthem dbpprop:author ?author .
}

SPARQL results

Community
  • 1
  • 1
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • Hot damn! That did it, and simplified the query quite a bit. What does the * signify? (and you were right - that other answer was similar, though I didn't see how it was working) – Bonjiro Jul 16 '15 at 14:19
  • @Bonjiro The `*` is one of the [property paths](http://www.w3.org/TR/sparql11-query/#propertypaths) supported in SPARQL 1.1. The pattern `a p* b` matches if there's a *path* from a to b consisting of zero or more occurrences of `p`. In the case that the path if of length zero, it means that a and b have to be the same. E.g., `x hasChild* ?y` would bind `?y` to `x` and all of `x`'s descendants. – Joshua Taylor Jul 16 '15 at 14:23
  • Excellent, and that's very useful. Thank you so much, Joshua! – Bonjiro Jul 16 '15 at 18:30
0

What about this?

PREFIX dbr: <http://dbpedia.org/resource/>

select dbr:France ?capital ?label where {
  {dbr:France a dbpedia-owl:Country.
   dbr:France dbpedia-owl:capital ?capital .
   ?capital rdfs:label ?label .
  }

 union {dbr:France dbpedia-owl:wikiPageRedirects ?redirectPage.
        ?redirectPage dbpedia-owl:capital ?capital.
        ?capital rdfs:label ?label .     
 }
}

Result

Ali Ismayilov
  • 1,707
  • 3
  • 22
  • 37
  • 1
    Hi Ali. I clarified the question. It's a matter of if it's possible to factor out the ?country portion by assigning the resource to a variable if it exists. – Bonjiro Jul 16 '15 at 14:08