0

I'm trying to get Individuals in my Ontology which have a certain property. I want all Individuals which are linked to a foot by the hasFoot property. In the past I used Jena's iterators, but now i want to use SPARQL. The Java code that creates my query:

String queryString =        
                "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>"+
                "PREFIX owl: <http://www.w3.org/2002/07/owl#>" +
                "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>" +
                "PREFIX test: <file:/test#>"+
                "select ?uri"+
                "where { "+
                "?uri test:hasFoot ?foot"+
                "} \n ";

But I don't get any results with this query. When I query for the properties of all triples I get these results:

"select ?prop "+
"where { "+
"?uri ?prop ?subj"+
"} \n ";
 <file:/test#hasFoot> 
 <file:/test#hasFoot> 
 <file:/test#hasFoot> 
 <file:/test#hasFoot> 
 <file:/test#hasAge>  
 <file:/test#hasName> 

So SPARQL queries are clearly working. I can even search for the rdf:types, so the rdf namespace works, only my namespace (test) doesnt seem to work. I have also tried to write out the whole property name ("file:/test#hasFoot") with no results. Does anyone have an idea what I am missing?

Here is my ontology:

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

  <rdf:Description rdf:about="file:/test#Foot2">
    <rdf:type rdf:resource="file:/test#Foot"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Peter">
    <test:hasHand rdf:resource="file:/test#Hand2"/>
    <test:hasHand rdf:resource="file:/test#Hand1"/>
    <test:hasFoot rdf:resource="file:/test#Foot6"/>
    <test:hasFoot rdf:resource="file:/test#Foot5"/>
    <test:hasName>Peter</test:hasName>
    <test:hasAge>98</test:hasAge>
    <rdf:type rdf:resource="file:/test#Individuum"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#hasName">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#DatatypeProperty"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Foot1">
    <rdf:type rdf:resource="file:/test#Foot"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Foot3">
    <rdf:type rdf:resource="file:/test#Foot"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Hand">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#hasAge">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#DatatypeProperty"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Human">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#hasFoot">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ObjectProperty"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Doggy">
    <test:hasFoot rdf:resource="file:/test#Foot4"/>
    <test:hasFoot rdf:resource="file:/test#Foot3"/>
    <test:hasFoot rdf:resource="file:/test#Foot2"/>
    <test:hasFoot rdf:resource="file:/test#Foot1"/>
    <test:hasAge>7</test:hasAge>
    <test:hasName>Doggy</test:hasName>
    <rdf:type rdf:resource="file:/test#Individuum"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Hand2">
    <rdf:type rdf:resource="file:/test#Hand"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Foot6">
    <rdf:type rdf:resource="file:/test#Foot"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#hasHand">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ObjectProperty"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Individuum">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Foot">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Ontology"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Foot5">
    <rdf:type rdf:resource="file:/test#Foot"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Hand1">
    <rdf:type rdf:resource="file:/test#Hand"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/test#Foot4">
    <rdf:type rdf:resource="file:/test#Foot"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
</rdf:RDF>
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
ImmaCute
  • 57
  • 7
  • 1
    In addition the problems with the `file` scheme that some answers have addressed, you also have a problem in your string concatenation. You're doing `"select ?uri" + "where { ..."` which produces `select ?uriwhere { ...". That's legal SPARQL, because the `where` is optional, but you don't have a variable `?uriwhere`, so even if your query has results, you won't get them. See [DBpedia Jena Query returning null](http://stackoverflow.com/q/15663510/1281433) and [empty ResultSet on second query (despite valid results with first)](http://stackoverflow.com/q/19949592/1281433). – Joshua Taylor Jun 25 '14 at 14:35
  • You are right. With a whitespace and the other solutions it works fine, now, ty. – ImmaCute Jun 25 '14 at 14:50
  • Even better is to avoid the *possibility* of making that mistake. As [AndyS commented](http://stackoverflow.com/questions/15663510/dbpedia-jena-query-returning-null#comment22245164_15664716), since it's optional, you can just leave it out. Just use `select ?uri { ... }`. Then it's impossible to have that particular bug, plus you get shorter code. – Joshua Taylor Jun 25 '14 at 14:58

2 Answers2

3

The reason this happens is not obvious, but concerns your poor choice of namespace: file:/test#.

file: URIs are pretty badly understood, and typically poorly implemented. In particular they are supposed to start file://hostname/ or (more commonly) just file:/// for local files.

Jena's query engine attempts to correct this, but significantly the data hasn't been corrected. We can see this using the arq command line tool:

$ arq --data data.rdf --query query.rq --explain
...
15:12:43 INFO  exec                 :: ALGEBRA
  (project (?uri)
    (bgp (triple ?uri <file:///test#hasFoot> ?foot)))

(note the <file:///test#hasFoot>)

Changing the namespace in both the data and query fixes the issue.

I suggest avoiding file: URIs. If you're just experimenting try http://example.com/ns# or similar.

user205512
  • 8,798
  • 29
  • 28
  • If one wishes to avoid using a an arbitrary `http:` scheme (in order to prevent implying a [Dereferenceable URI](http://en.wikipedia.org/wiki/Dereferenceable_Uniform_Resource_Identifier)), one can use domain-specific [URN](http://en.wikipedia.org/wiki/Uniform_resource_name)S from the `urn:`-scheme or an internal scheme prefixed by `x-`, such as `x-myscheme:`. – Rob Hall Jun 25 '14 at 14:35
  • I'll take a closer look into namespaces these days. File:///test does it for now, though. Although i marked the older reply as solved, ill upvote your answer as soon as I can, it was a big help, too. – ImmaCute Jun 25 '14 at 14:47
1

Your custom scheme is missing an authority and isn't a valid IRI.

You can test the IRIs that your using by using one of the IRIFactory types that exist in jena. For example, if I were to run one of your IRIs through:

@Test
public void correctUri() {
   final IRIFactory factory = IRIFactory.iriImplementation();
   final IRI iri = factory.construct("file:/test#johnsFoot");
}

I get the following exception, indicating that the authority portion of the IRI is missing, so it's not an IRI:

org.apache.jena.iri.impl.IRIImplException: <file:/test#johnsFoot> Code: 57/REQUIRED_COMPONENT_MISSING in AUTHORITY: A component that is required by the scheme is missing.
    at org.apache.jena.iri.impl.AbsIRIFactoryImpl.throwAnyErrors(AbsIRIFactoryImpl.java:65)
    at org.apache.jena.iri.impl.AbsIRIFactoryImpl.construct(AbsIRIFactoryImpl.java:48)
    at SO_Test.correctUri(SO_Test.java:87)

Updating your ontology to use file://test# rather than file:/test# and running the following query:

@Test
public void getAllProperties2() {
    final Query query = QueryFactory.create(
        "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>"+
        "PREFIX owl: <http://www.w3.org/2002/07/owl#>" +
        "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>" +
        "PREFIX test: <file://test#>"+
        "select * "+
        "where { "+
        "?uri ?prop ?subj"+
        "} \n "
    );

    final QueryExecution exec = QueryExecutionFactory.create(query, model1);
    final ResultSetRewindable results = ResultSetFactory.copyResults(exec.execSelect());
    exec.close();

    ResultSetFormatter.out(System.out, results, query);
    results.reset();
}

Results in the output that you expect. Most notable is that the prefixes that you want to see are associated with your elements. The output is as follows:

---------------------------------------------------------
| uri             | prop         | subj                 |
=========================================================
| test:Hand       | rdf:type     | owl:Class            |
| test:Foot3      | rdf:type     | owl:NamedIndividual  |
| test:Foot3      | rdf:type     | test:Foot            |
| test:Human      | rdf:type     | owl:Class            |
| <file://test>   | rdf:type     | owl:Ontology         |
| test:Hand2      | rdf:type     | owl:NamedIndividual  |
| test:Hand2      | rdf:type     | test:Hand            |
| test:Individuum | rdf:type     | owl:Class            |
| test:hasName    | rdf:type     | owl:DatatypeProperty |
| test:Foot2      | rdf:type     | owl:NamedIndividual  |
| test:Foot2      | rdf:type     | test:Foot            |
| test:Hand1      | rdf:type     | owl:NamedIndividual  |
| test:Hand1      | rdf:type     | test:Hand            |
| test:Foot1      | rdf:type     | owl:NamedIndividual  |
| test:Foot1      | rdf:type     | test:Foot            |
| test:hasAge     | rdf:type     | owl:DatatypeProperty |
| test:hasFoot    | rdf:type     | owl:ObjectProperty   |
| test:hasHand    | rdf:type     | owl:ObjectProperty   |
| test:Peter      | rdf:type     | owl:NamedIndividual  |
| test:Peter      | rdf:type     | test:Individuum      |
| test:Peter      | test:hasAge  | "98"                 |
| test:Peter      | test:hasName | "Peter"              |
| test:Peter      | test:hasFoot | test:Foot5           |
| test:Peter      | test:hasFoot | test:Foot6           |
| test:Peter      | test:hasHand | test:Hand1           |
| test:Peter      | test:hasHand | test:Hand2           |
| test:Foot6      | rdf:type     | owl:NamedIndividual  |
| test:Foot6      | rdf:type     | test:Foot            |
| test:Foot5      | rdf:type     | owl:NamedIndividual  |
| test:Foot5      | rdf:type     | test:Foot            |
| test:Doggy      | rdf:type     | owl:NamedIndividual  |
| test:Doggy      | rdf:type     | test:Individuum      |
| test:Doggy      | test:hasName | "Doggy"              |
| test:Doggy      | test:hasAge  | "7"                  |
| test:Doggy      | test:hasFoot | test:Foot1           |
| test:Doggy      | test:hasFoot | test:Foot2           |
| test:Doggy      | test:hasFoot | test:Foot3           |
| test:Doggy      | test:hasFoot | test:Foot4           |
| test:Foot4      | rdf:type     | owl:NamedIndividual  |
| test:Foot4      | rdf:type     | test:Foot            |
| test:Foot       | rdf:type     | owl:Class            |
---------------------------------------------------------

With your previous data, the following query results in different results:

@Test
public void getAllProperties() {
    final Query query = QueryFactory.create(
        "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>"+
        "PREFIX owl: <http://www.w3.org/2002/07/owl#>" +
        "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>" +
        "PREFIX test: <file:/test#>"+
        "select * "+
        "where { "+
        "?uri ?prop ?subj"+
        "} \n "
    );

    final QueryExecution exec = QueryExecutionFactory.create(query, model0);
    final ResultSetRewindable results = ResultSetFactory.copyResults(exec.execSelect());
    exec.close();

    ResultSetFormatter.out(System.out, results, query);
    results.reset();
}

results in:

----------------------------------------------------------------------------
| uri                     | prop                 | subj                    |
============================================================================
| <file:/test#Hand>       | rdf:type             | owl:Class               |
| <file:/test#Foot1>      | rdf:type             | owl:NamedIndividual     |
| <file:/test#Foot1>      | rdf:type             | <file:/test#Foot>       |
| <file:/test#hasFoot>    | rdf:type             | owl:ObjectProperty      |
| <file:/test#Doggy>      | rdf:type             | owl:NamedIndividual     |
| <file:/test#Doggy>      | rdf:type             | <file:/test#Individuum> |
| <file:/test#Doggy>      | <file:/test#hasName> | "Doggy"                 |
| <file:/test#Doggy>      | <file:/test#hasAge>  | "7"                     |
| <file:/test#Doggy>      | <file:/test#hasFoot> | <file:/test#Foot1>      |
| <file:/test#Doggy>      | <file:/test#hasFoot> | <file:/test#Foot2>      |
| <file:/test#Doggy>      | <file:/test#hasFoot> | <file:/test#Foot3>      |
| <file:/test#Doggy>      | <file:/test#hasFoot> | <file:/test#Foot4>      |
| <file:/test#Foot6>      | rdf:type             | owl:NamedIndividual     |
| <file:/test#Foot6>      | rdf:type             | <file:/test#Foot>       |
| <file:/test#hasHand>    | rdf:type             | owl:ObjectProperty      |
| <file:/test#hasName>    | rdf:type             | owl:DatatypeProperty    |
| <file:/test>            | rdf:type             | owl:Ontology            |
| <file:/test#Foot5>      | rdf:type             | owl:NamedIndividual     |
| <file:/test#Foot5>      | rdf:type             | <file:/test#Foot>       |
| <file:/test#Human>      | rdf:type             | owl:Class               |
| <file:/test#Hand2>      | rdf:type             | owl:NamedIndividual     |
| <file:/test#Hand2>      | rdf:type             | <file:/test#Hand>       |
| <file:/test#Foot4>      | rdf:type             | owl:NamedIndividual     |
| <file:/test#Foot4>      | rdf:type             | <file:/test#Foot>       |
| <file:/test#hasAge>     | rdf:type             | owl:DatatypeProperty    |
| <file:/test#Hand1>      | rdf:type             | owl:NamedIndividual     |
| <file:/test#Hand1>      | rdf:type             | <file:/test#Hand>       |
| <file:/test#Foot3>      | rdf:type             | owl:NamedIndividual     |
| <file:/test#Foot3>      | rdf:type             | <file:/test#Foot>       |
| <file:/test#Peter>      | rdf:type             | owl:NamedIndividual     |
| <file:/test#Peter>      | rdf:type             | <file:/test#Individuum> |
| <file:/test#Peter>      | <file:/test#hasAge>  | "98"                    |
| <file:/test#Peter>      | <file:/test#hasName> | "Peter"                 |
| <file:/test#Peter>      | <file:/test#hasFoot> | <file:/test#Foot5>      |
| <file:/test#Peter>      | <file:/test#hasFoot> | <file:/test#Foot6>      |
| <file:/test#Peter>      | <file:/test#hasHand> | <file:/test#Hand1>      |
| <file:/test#Peter>      | <file:/test#hasHand> | <file:/test#Hand2>      |
| <file:/test#Foot2>      | rdf:type             | owl:NamedIndividual     |
| <file:/test#Foot2>      | rdf:type             | <file:/test#Foot>       |
| <file:/test#Foot>       | rdf:type             | owl:Class               |
| <file:/test#Individuum> | rdf:type             | owl:Class               |
----------------------------------------------------------------------------

It seems that jena does not make a best-guess effort at enforcing the qname/prefix standards on invalid IRIs.

Rob Hall
  • 2,693
  • 16
  • 22
  • As a bonus note, should you desire to use a custom `scheme`-portion of your IRI, note that Jena can also scream if you aren't using an actual IANA registered scheme. For application-specific and experimental content, Jena allows `x-`-prefixed schemes when you want to be strict. For example, I may use `x-test://` or `x-myApplicationName://` to indicate that I'm using a scheme that is not registered with IANA. – Rob Hall Jun 25 '14 at 14:24
  • 1
    The prefix choice isn't the only issue here. The string concatenation "select ?uri" + "where ..." makes the query `select ?uriwhere { … }`, which is legal, since `where` is optional, but There's probably no variable named "?uriwhere". – Joshua Taylor Jun 25 '14 at 14:31
  • That's a good point that I glossed over by using `SELECT * WHERE`. The main reason he got no results for his query was the concatenation issue. I got results for my query, which demonstrated the unexpected prefix. Good catch. – Rob Hall Jun 25 '14 at 14:39