Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my SPARQL query return the URI of a resource instead of its name?

I want to get all classes of my ontology. This is a part of my ontology file in RDF/XML format created by Protege:

<!-- http://www.w3.org/2002/07/owl#aqua -->

<Class rdf:about="&owl;aqua"/>

<!-- http://www.w3.org/2002/07/owl#varioPerfect -->

<Class rdf:about="&owl;varioPerfect"/>

I wrote this query, which works properly in Protege, but when I use it in dotNetRDF it returns the full URI of the class instead of just its name.

 public string[] ontologysearch()
{
    List<string> list = new List<string>();
    TripleStore store = new TripleStore();
    Graph mygraph = new Graph();
    mygraph.LoadFromFile("D:/msc/search-engine/project/catalogXML.owl");


      store.Add(mygraph);


      string sparqlQuery1 = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>"
          + "PREFIX owl: <http://www.w3.org/2002/07/owl#>"
          + "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>"
          + "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"
          + "SELECT distinct ?cls1"
          + " WHERE{"
          + "  ?cls1 a owl:Class .}";

      SparqlQueryParser sparqlParser = new SparqlQueryParser();
      SparqlQuery query = sparqlParser.ParseFromString(sparqlQuery1);
      InMemoryDataset ds = new InMemoryDataset(mygraph);

      //Get the Query processor
      ISparqlQueryProcessor processor = new LeviathanQueryProcessor(ds);
      Object results = processor.ProcessQuery(query);
      if (results is SparqlResultSet)
      {
          SparqlResultSet r = results as SparqlResultSet;

          foreach (SparqlResult res in r)
          {

              list.Add(res["cls1"].ToString());
          }
      }

      return list.ToArray();

}

The result I expected was just "aqua" but in fact is "http://www.w3.org/2002/07/owl#aqua". Why does this happen, and how can I retrieve the name instead?

like image 479
zaf y Avatar asked Feb 12 '15 14:02

zaf y


1 Answers

Non-anonymous resources in RDF and OWL are identified by IRIs. Your ontology clearly says that http://www.w3.org/2002/07/owl#aqua is class. If you ask for the class, that's what you should get. It might be that Protege strips off the http://www.w3.org/2002/07/owl# part when it displays the result, but the result is still actually the IRI.

Note: you really should not be defining new classes whose IRIs begin with the standard OWL namespace. You should be defining your own prefix, typically related to the ontology IRI.

If you just want to get the string "aqua" as the result, you have two options. The first (and preferred) approach is to retrieve the rdfs:label of the class, if it has one, which should be the string name of the class. If for some reason that doesn't work, you can take the string value of the URI and strip off the string value of the prefix. Here are examples of both approaches on the DBpedia SPARQL endpoint:

select ?class ?label where {
  ?class a owl:Class ; rdfs:label ?label
  filter langMatches(lang(?label),'en')
}
limit 10

SPARQL results (with rdfs:label)

select ?class ?name where {
  ?class a owl:Class
  bind(strafter(str(?class),str(dbpedia-owl:)) as ?name)
}
limit 10

SPARQL results (by stripping the prefix)

Stripping off the prefix of a URI for display purposes is, in general, not a recommended practice, as it assumes that the URI has a human-readable form. In the case of DBPedia that happens to work, but plenty of datasets have URIs with internal codes rather than human-readable names. So if the rdfs:label (which is explicitly defined to be the human-readable representation of the resource) is available, you should try and always use that.

like image 58
Joshua Taylor Avatar answered Sep 19 '22 09:09

Joshua Taylor