我正在使用jena框架来处理我的猫头鹰本体。
我想编写一个方法,可以找到它所属的超级类,它就在Thing类之下。
例如,如果有5级层次结构,则说第一级是Thing,第二级是SecondAncestor,第三级是ThirdAncestor,依此类推。如果我通过了一个类FifthAncestor,我想要返回SecondAncestor因为Thing没有任何意义。如果我通过ThirdAncestor,我想返回SecondAncestor。换句话说,它属于大多数通用类,但不属于顶级类(Thing)。答案 0 :(得分:1)
方法一
这将取决于您的模型具有推理器,因为owl:Thing
通常不会声明为模型,因此不会出现在没有推理器的模型中。鉴于此,那么:
OntModel m = ... your OntModel ...;
OntClass thing = m.getOntClass( OWL.Thing.getURI() );
for (Iterator<OntClass> i = thing.listSubClasses(true); i.hasNext(); ) {
OntClass hierarchyRoot = i.next();
....
}
请注意direct = true
来电中使用标记listSubClasses()
。
方法二
不需要推理员。
for (Iterator<OntClass> i = m.listHierarchyRootClasses(); i.hasNext(); ) {
OntClass hierarchyRoot = i.next();
....
}
请注意,此方法将返回根类,即使它们是表示类表达式的匿名资源。出于UI目的,这通常不是您想要的(很难以有意义的方式向用户显示bNode)。在这种情况下,请改用OntTools.namedHierarchyRoots。
<强>更新强>
我现在明白Alan希望作为特定类的父类的根类,而namedHierarchyRoots
将列出类层次结构的根类的所有。请注意,通常,类与Thing
之间可能包含零个,一个或多个命名超类。
无论如何,这是我如何解决这个问题。同样,此解决方案假定模型不使用推理器。有了推理器,它就会容易得多:
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;
}
答案 1 :(得分:0)
我在不使用推理器的情况下以下列方式找到解决方案。它不是完美的解决方案,但它有效。如果你将未命名的(匿名)类作为超类,这个解决方案也解决了问题。
首先,我创建了一个存储顶级类名的数组。
一种简单的方法,在我创建的数组中搜索,如果传递的参数是顶级类。
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;
}
然后找到东西下最常见类的主要方法:
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;
}