6

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?

Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73
zaf y
  • 153
  • 3
  • 13

1 Answers1

9

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.

Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • 6
    As usual very thorough. One additional remark: it should be noted that stripping off the prefix of a IRI for display purposes is, in general, not a recommended practice, as it assumes that the IRI has a human-readable form. In the case of DBPedia that happens to work, but plenty of datasets have IRIs 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. – Jeen Broekstra Feb 12 '15 at 19:05
  • 1
    @JeenBroekstra Agreed. It appears that OP is using Protege, and while the latest versions might take the user-provided name and make an rdfs:label automatically, earlier versions just concatenate the name with the ontology IRI. If that's the case, then the prefix stripping version will be more useful. That said, I agree that the rdfs:label version is better practice, since the IRIs should really be treated as opaque. – Joshua Taylor Feb 12 '15 at 19:13
  • Thank you very much of all. however the second solution did not work for me! with all changes and effort it had an error of "Unknown function strafter ...". but label was good. – zaf y Feb 16 '15 at 21:58
  • 1
    @zafy strafter is available in SPARQL 1.1. If you're using the first version (SPARQL 1.0), you'll need to use **regex** instead. – Joshua Taylor Feb 17 '15 at 03:28