使用Jena在Top Class之前找到一个班级的超级班级

时间:2012-11-15 01:32:09

标签: jena ontology owl

我正在使用jena框架来处理我的猫头鹰本体。

我想编写一个方法,可以找到它所属的超级类,它就在Thing类之下。

例如,如果有5级层次结构,则说第一级是Thing,第二级是SecondAncestor,第三级是ThirdAncestor,依此类推。如果我通过了一个类FifthAncestor,我想要返回SecondAncestor因为Thing没有任何意义。如果我通过ThirdAncestor,我想返回SecondAncestor。换句话说,它属于大多数通用类,但不属于顶级类(Thing)。

2 个答案:

答案 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;
}