Question

I have the following OWL classes with two individuals:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rdf:RDF [
  <!ENTITY owl "http://www.w3.org/2002/07/owl#">
  <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
  <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">
]>

<rdf:RDF xmlns="http://www.example.org/message#"
         xmlns:owl="http://www.w3.org/2002/07/owl#"
         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
         xmlns:xsd ="http://www.w3.org/2001/XMLSchema#">

  <owl:Ontology rdf:about="">
    <rdfs:comment>The Common Alerting Protocol Ontology</rdfs:comment>
    <rdfs:label>CAP Ontology</rdfs:label> 
  </owl:Ontology>

  <owl:Class rdf:ID="Message">
    <rdfs:label>CAP alert message</rdfs:label>
    <rdfs:comment>...</rdfs:comment>
  </owl:Class>

  <owl:Class rdf:ID="AlertStatus">
    <owl:oneOf rdf:parseType="Collection">
      <owl:Thing rdf:about="#Actual" />
      <owl:Thing rdf:about="#Exercise" />
      <owl:Thing rdf:about="#System" />
      <owl:Thing rdf:about="#Test" />
      <owl:Thing rdf:about="#Draft" />
    </owl:oneOf>
  </owl:Class>

  <owl:DatatypeProperty rdf:ID="hasSender">
    <rdfs:domain rdf:resource="#Message" />
    <rdfs:range rdf:resource="&xsd;string" />
  </owl:DatatypeProperty>  

  <owl:ObjectProperty rdf:ID="hasStatus">
    <rdfs:domain rdf:resource="#Message"/>
    <rdfs:range rdf:resource="#AlertStatus"/>
  </owl:ObjectProperty>

  <Message rdf:ID="KSTO1055887203">
    <hasSender>KSTO</hasSender>
    <hasStatus rdf:resource="#Actual"/>
  </Message>

  <Message rdf:ID="KAR0-0306112239-SW">
    <hasSender>KARO</hasSender>
    <hasStatus rdf:resource="#Actual"/>
  </Message>

</rdf:RDF>

If I query with:

PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE { ?subject foo:hasSender ?object }

, I get:

----------------------------------
| subject              |  object |
==================================
| KAR0-0306112239-SW   | "KARO"@ |
| KSTO1055887203       | "KSTO"@ |
----------------------------------

When I try to retrieve only the message with hasSender the value "KARO":

PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE { ?subject foo:hasSender "KARO"}

, the query returns no results. Are there any issues with my RDF/OWL. Am I missing a Namespace or something?

EDIT: I use Protege v4.3.0 and I get no results whether I start the reasoner (HermiT) or not. I also edited the output of my first query. There is a trailing '@' symbol, I am not sure if it's of any significance. I don't declare the language of the strings involved anywhere (I mention this cause my understanding is that the @ symbol is used to declare the language of the string like "KARO"@en).

Was it helpful?

Solution

You're not using absolute IRIs

It's generally easier to figure out the right SPARQL queries to write if the data is viewed in the Turtle or N3 serializations, because those serializations are much closer to the syntax of SPARQL queries. In this case, your data is:

@prefix :      <http://www.example.org/message#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#System>
        a       owl:Thing .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Message>
        a             owl:Class ;
        rdfs:comment  "..." ;
        rdfs:label    "CAP alert message" .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Actual>
        a       owl:Thing .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#hasStatus>
        a            owl:ObjectProperty ;
        rdfs:domain  <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Message> ;
        rdfs:range   <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#AlertStatus> .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Draft>
        a       owl:Thing .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#KAR0-0306112239-SW>
        a           :Message ;
        :hasSender  "KARO" ;
        :hasStatus  <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Actual> .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Exercise>
        a       owl:Thing .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf>
        a             owl:Ontology ;
        rdfs:comment  "The Common Alerting Protocol Ontology" ;
        rdfs:label    "CAP Ontology" .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#KSTO1055887203>
        a           :Message ;
        :hasSender  "KSTO" ;
        :hasStatus  <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Actual> .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#hasSender>
        a            owl:DatatypeProperty ;
        rdfs:domain  <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Message> ;
        rdfs:range   xsd:string .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Test>
        a       owl:Thing .

<file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#AlertStatus>
        a          owl:Class ;
        owl:oneOf  ( <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Actual> <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Exercise> <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#System> <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Test> <file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf#Draft> ) .

Now, it's worth pointing out that you probably don't have a file: file:///home/taylorj/tmp/sparql-owl-individuals/data.rdf, so it might be surprising to see that in your data. The problem is that there's no XML base declared in your original data, so the actual IRIs that you've got are ambiguous, and depend, in this case, on where the data is actually located.

In the RDF/XML serialization, you can provide an XML base with the xml:base attribute. In your case, it would be something like:

<rdf:RDF xmlns="http://www.example.org/message#"
         xml:base="http://www.example.org/message#"
         xmlns:owl="http://www.w3.org/2002/07/owl#"
         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
         xmlns:xsd ="http://www.w3.org/2001/XMLSchema#">

The prefix-less xmlns serves as a prefix for prefix-less element names, but you still need an XML base for resolving the rdf:about attributes on elements.

Query results

Even with those relative IRIs, I still be results to your queries. Using Jena's command line sparql tool, I get the following results for the queries:


PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE { ?subject foo:hasSender ?object }
------------------------------------------
| subject                       | object |
==========================================
| <data.rdf#KAR0-0306112239-SW> | "KARO" |
| <data.rdf#KSTO1055887203>     | "KSTO" |
------------------------------------------

PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE { ?subject foo:hasSender "KARO"}
---------------------------------
| subject                       |
=================================
| <data.rdf#KAR0-0306112239-SW> |
---------------------------------

After your edit, I'm still not quite sure what's going on, but literals with language tags in RDF are written as their lexical form as a string followed by @ followed by the language tag. E.g.,

"Joshua"@en
"Giosuè"@it

I'm not sure what it means if you're seeing results that look like that, but without an actual language tag. Perhaps you have some literals with language tags, but wherein the language tag is the empty string. In any case, you can match those cases by changing your query to look for literals whose lexical form is "KARO":

PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE {
  ?subject foo:hasSender ?sender .
 filter( str(?sender) = "KARO" )
}

That shouldn't make a difference on the data that you've shown us, but if you've modified it at all (like you did with the output from the query), it's possible that this will resolve your issue. I know that it's also the case that the SPARQL query functionality in Protégé doesn't run the query on the input file that you give it, but rather on another temporary file that it writes out. It's possible that that could add some empty language tags, too.

Possible reasoner interactions

Depending on what you're doing to view the results, though, I suppose it's possible that since these values are relative IRIs, you might be trying to display them in some way that requires an absolute IRI. (I don't know what such a way would be, but I don't know everything about your setup.)

If you're using an OWL reasoner, it's possible, too, that the data that the reasoner provides to the query engine is different than the data you see in the file. As AndyS pointed out in the comments, since the range of the hasSender property is being declared as an xsd:string, it might be that the reasoner is taking the triple

<data.rdf#KAR0-0306112239-SW> hasSender "KARO" 

and transforming it into

<data.rdf#KAR0-0306112239-SW> hasSender "KARO"^^xsd:string

for you, in which case you'd need to use the query

PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foo: <http://www.example.org/message#>
SELECT * WHERE { ?subject foo:hasSender "KARO"^^xsd:string }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top