8

I can include URIs and variables in my queries, but I can't include literals in my queries.

Here, I have some code which successfully reads an RDF file, finds all the RDF triples with skos:prefLabels, counts them, and then identifies a couple of specific ones from a set of keywords:

import rdflib.plugins.sparql as sparql
import rdflib
import rdflib.graph as g

graph = g.Graph()
# Read the RDF file
graph.parse(
   'h:\......SKOSTaxonomy.rdf',
   format='xml')

# Build and execute the query
q = sparql.prepareQuery('SELECT ?s ?p ?o WHERE { ?s ?p ?o .}')
p = rdflib.URIRef("http://www.w3.org/2004/02/skos/core#prefLabel")
qres = graph.query(q, initBindings = {'p' : p})

print len(qres)

# Look for keywords among the results
keywords = set([u'Jackknifing', 'Technology-mapping', 'Something random'])

for (subj, pred, obj) in qres:
    if obj.value in keywords:
        print obj.value

As expected, this code prints:

2299
Jackknifing
Technology-mapping

since Jackknifing and Technology-mapping are prefLabels in the file.

What I really want to do is to construct and execute a Sparql query to look for each keyword in turn. But this is where I come unstuck, because I can't put a string into the query. I have tried this, for example:

o = rdflib.Literal(u'Jackknifing')
qres = graph.query(q, initBindings = {'p' : p, 'o' : o})

but qres is empty. I have also tried putting a literal explicitly into the query, e.g.

q = sparql.prepareQuery('SELECT ?s ?p WHERE { ?s ?p "Technology-mapping" .}')
qres = graph.query(q, initBindings = {'p' : p})

but that returns an empty result too.

How are literals included in a query?

Diana Bental
  • 83
  • 1
  • 4
  • 1
    Can you show your data by any chance? Is is possible that the literals in your data have datatypes, or are strings with language tags? If they are, and if you are injecting an untyped literal, or a literal with no language tag, things won't match. If you can show your data, and can show the final SPARQL query with the `initBindings` applied (if you can do this with RDFLib/RDFLib-SPARQL), the problem might become very clear. – Joshua Taylor Jun 17 '13 at 12:24
  • Aha - yes there are language tags in the file though not datatypes. So the query – Diana Bental Jun 17 '13 at 13:38
  • 1
    Aha - yes there are language tags in the file though not datatypes. And the query q = sparql.prepareQuery('SELECT ?s ?p WHERE { ?s ?p "Technology-mapping"@en .}') works properly. So it does look as if that's the problem, many thanks. So now I need to figure out how to add a language tag to the literal. I don't know how to print the query that's been constructed - I'll update if I figure it out. – Diana Bental Jun 17 '13 at 13:46

1 Answers1

5

If the literals in your data have datatypes, or are strings with language tags, then a plain literal, that is, one without a datatype or language tag, injected into the query won't match.

The RDFLib docs on Literals show ways of creating literals with datatypes, but don't have an example of creating one with a language tag. However, the docs also have the source attached and the signature for Literal's __new__ is:

static __new__(lexical_or_value, lang=None, datatype=None, normalize=None)

Since the literal in your data has a language tag ('en'), you should create your literal as

o = rdflib.Literal(u'Jackkifing',lang='en')

so that the language tag is associated with the literal.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • @DianaBental Glad to hear you found it! Looking at the docs, I noticed a _source_ link that I hadn't before, and found the `lang` argument in the source too. I've updated my answer to include the information that we discussed in the comments, and the `lang` argument. – Joshua Taylor Jun 18 '13 at 12:07