4

I'm using C# to execute query on my N3 data files. How can i limit the result to the first level of children of a node. For example:

project
      |
      |__ main
      |      |__m1
      |      |__m2
      |   
      |__ SUB
          |__A
          |  |__A1
          |  |__A2
          | 
          |__B
          |__C
          |  |__C1
          |  
          |__D

an example query which result all level of nodes for SUB:

 select ?object where { 
 :SUB rdfs:superClassOf* ?object
 }

the result will be:

          |__A
          |  |__A1
          |  |__A2
          | 
          |__B
          |__C
          |  |__C1
          |  
          |__D

But i want to limit the result to the first level of children like this:

          |__A
          |__B
          |__C
          |__D
osyan
  • 1,518
  • 21
  • 47

1 Answers1

6

Selecting paths of length one

The property path using * finds paths of length zeor or greater. If you want paths of length exactly one, just remove the *:

 select ?object where { 
   :SUB rdfs:superClassOf ?object
 }

I'd note though that RDFS only defines rdfs:subClassOf, not rdfs:superClassOf which you've used in your query. I'll assume that it's just a typo in the question, though. I think the actual query you'd want would be:

select ?subclass where { 
  ?subclass rdfs:subClassOf :SUB
}

Selecting arbitrary length paths

The solutions in this section are based on an answer to a question about finding the position of elements in an RDF list. Consider this data:

@prefix : <urn:ex:> .

:a :p :b, :c .
:b :p :d, :e .

This query finds chains on p along with the lengths of the chains:

prefix : <urn:ex:>

select ?sub ?sup (count(?mid)-1 as ?distance) where { 
  ?sub :p* ?mid .
  ?mid :p* ?sup .
}
group by ?sub ?sup
order by ?sub ?sup

$ arq --data data.n3 --query query.sparql
------------------------
| sub | sup | distance |
========================
| :a  | :a  | 0        |
| :a  | :b  | 1        |
| :a  | :c  | 1        |
| :a  | :d  | 2        |
| :a  | :e  | 2        |
| :b  | :b  | 0        |
| :b  | :d  | 1        |
| :b  | :e  | 1        |
| :c  | :c  | 0        |
| :d  | :d  | 0        |
| :e  | :e  | 0        |
------------------------

Since we can get the length of the paths we can filter on that length and get just the ones we want. For instance:

prefix : <urn:ex:>

select ?sub ?sup where { 
  { 
    select ?sub ?sup (count(?mid)-1 as ?distance) where { 
      ?sub :p* ?mid .
      ?mid :p* ?sup .
    }
    group by ?sub ?sup
    order by ?sub ?sup
  }
  filter( ?distance = 2 )
  # filter ( ?distance > 2 )   # alternative
  # filter ( ?distance < 10 )  # alternative
}

$ arq --data data.n3 --query query.sparql
-------------
| sub | sup |
=============
| :a  | :d  |
| :a  | :e  |
-------------

When you just want paths of small, but specific length, you can expand the property path manually. E.g., for paths of length two:

prefix : <urn:ex:>

select ?sub ?sup {
  ?sub :p/:p ?sup .
}

For a range of numbers, e.g., 1­–2, you can use the ? which matches zero or one:

prefix : <urn:ex:>

select ?sub ?sup {
  ?sub :p/:p? ?sup .
}

For more about property paths, be sure to take a look at section 9 Property Paths in the SPARQL 1.1 specification.

Community
  • 1
  • 1
Joshua Taylor
  • 80,876
  • 9
  • 135
  • 306
  • thanks again. and what about getting result for n level? `rdfs:superClass` is what i defined for some purpose. – osyan Aug 08 '13 at 14:50
  • 2
    @osyan You shouldn't define properties in the RDFS namespace. Many tools will treat the namespace as reserved, and complain if you use an IRI that isn't defined by the standards. Doing exactly one is trivial, and doing any number (with `*`) is easy, but doing a specific number is a bit more complicated. I'll update the answer with an example though. – Joshua Taylor Aug 08 '13 at 14:54
  • i need to define relationships like superclass, partOf ,... between my classes in my ontology. Protege just has the subclassof as default, and do not allow defining relationship between classes except the last level(instances). is it wrong to define rdfs:superClassOF and rdfs:partOf between the owl class in hierarchy? – osyan Aug 08 '13 at 15:30
  • this the code for a concept in my hierarchy ` ` ,is it wrong? – osyan Aug 08 '13 at 15:59
  • 2
    @osyan, there is nothing wrong with defining your own relationships. Joshua's point is that you shouldn't create your own relations using the rdfs namespace. So creating `rdfs:superClassOf` is wrong, but creating `my:superClassOf` is fine (assuming the prefix `my` is mapped to some namespace under your contro). – Jeen Broekstra Aug 09 '13 at 01:16
  • 1
    @JeenBroekstra Thanks! That was exactly the point I was trying to make. Well put! – Joshua Taylor Aug 09 '13 at 04:41
  • JoshuaTaylor & JeenBroekstra : Thank you! – osyan Aug 12 '13 at 13:54