Reputation: 463
I am using jena framework to process my owl ontology.
I want to write a method which can find the super class it belongs which is just under the Thing class.
Four example, if there are 5 level hierarchy, lets say first level is Thing, second level is secondAncestor, third level is ThirdAncestor and so on. If I pass a class FifthAncestor, I want to return SecondAncestor because Thing does not make any sense. If I pass ThirdAncestor, I want to return SecondAncestor. In other words, most general class it belongs to but not the top one (Thing).
Upvotes: 0
Views: 1901
Reputation: 13305
Method one
This will depend on your model having a reasoner, because owl:Thing
isn't normally asserted into a model, and so won't be present in a model with no reasoner. Given that, then:
OntModel m = ... your OntModel ...;
OntClass thing = m.getOntClass( OWL.Thing.getURI() );
for (Iterator<OntClass> i = thing.listSubClasses(true); i.hasNext(); ) {
OntClass hierarchyRoot = i.next();
....
}
Note the use of the flag direct = true
in the listSubClasses()
call.
Method two
Does not require a reasoner.
for (Iterator<OntClass> i = m.listHierarchyRootClasses(); i.hasNext(); ) {
OntClass hierarchyRoot = i.next();
....
}
Note that this method will return the root classes, even if they are anonymous resources representing a class expression. For UI purposes, this often isn't what you want (it's hard to display a bNode in a meaningful way to a user). In this case, use OntTools.namedHierarchyRoots instead.
Update
I now understand that Alan wants the root classes that are parents of a particular class, whereas namedHierarchyRoots
will list all of the root classes of the class hierarchy. Note that, in general, a class may have zero, one or many named-superclasses between it and Thing
.
Anyway, here's how I would solve this. Again, this solution assumes the model is not using a reasoner. With a reasoner, it would be much easier:
private boolean hasSubClassTransitive( OntClass parent, OntClass child ) {
return OntTools.findShortestPath( child.getOntModel(), child, parent,
new OntTools.PredicateFilter( RDFS.subClassOf ) ) != null;
}
public List<OntClass> namedRootsOf( OntClass c ) {
List<OntClass> cRoots = new ArrayList<OntClass>();
for (OntClass root: OntTools.namedHierarchyRoots( c.getOntModel() )) {
if (hasSubClassTransitive( root, c )) {
cRoots.add( root );
}
}
return cRoots;
}
Upvotes: 1
Reputation: 463
I find solution in following way without using reasoner. It is not perfect solution but it works. This solution also solves problem, if you get unnamed (anonymous) class as super class.
First I created an array which stores top level class names.
A simple method which searches in my created array, if the passed parameter is a top class.
public Boolean IsTopClass(String ontologyClass)
{
//NS is URI of ontology
String onClass=ontologyClass.replace(NS, "");
for(String oClass: topLevelClassList)
{
if(oClass.equalsIgnoreCase(onClass))
return true;
}
return false;
}
Then the main method which finds most general class under thing:
public String FindSuperClassUnderThing(OntClass subClass)
{
OntClass prevSubClass=subClass;
OntClass prevprevSubClass=null;
String topClass="";
String supClass=subClass.toString();
ExtendedIterator<OntClass> superClassList=null;
while(!this.IsTopClass(topClass))
{
prevprevSubClass=prevSubClass;
prevSubClass=prevSubClass.getSuperClass();
//if returned class is a anonymous class (not a named one)
//get list of superclasses and check if there is a topclass
//inside the super class list
if(!prevSubClass.toString().startsWith(NS))
{
prevSubClass=prevprevSubClass;
superClassList= prevSubClass.listSuperClasses();
while(superClassList.hasNext())
{
OntClass OntClassFromList= superClassList.next();
if(this.IsTopClass(OntClassFromList.toString()))
{
topClass= OntClassFromList.toString();
}
}
}
else
{
if (this.IsTopClass(prevSubClass.toString()))
{
topClass= prevSubClass.toString();
}
}
}
return topClass;
}
Upvotes: 0