JENA操作本体

来源:互联网 发布:uwp截图软件 编辑:程序博客网 时间:2024/05/21 09:54

---------------------------------------------------------------

基本概念

一个本体允许程序以一种开放有意义的方式明确一个关心的领域里的相关概念和关系。比如“wine”(酒)这个领域的概念,红酒白酒,葡萄品种,酿酒年份,酿酒厂等,关系如“酿酒厂生产酒”“酒有一个生产年份”。这个酒的本体可能被一个特定的应用开发出来。它需要有一个很好的数据元结构,并且可以被发布和重用。


写一个本体的方法有很多,在实际中,本体的内容很大程度取决于它所支持的应用的种类。Jena中,并不关注一个本体的需要最小的必要组件,而是支持一个更加通用的技术。Jena是一个基础RDF平台。仅支持基于RDF形式的本体。


描述本体的能力: RDF(RDFS) —>OWL


---------------------------------------------------------------
创建本体模型
Jena本体模型是Jena的RDF模型的拓展,提供了处理本体更加有力的工具。
本体模型通过Jena的ModelFactory创建。
最简单的创建方式: OntModel m = ModelFactory.createOntologyModel();
将创建一个默认设置的本体模型。(OWL-full,内存存储,RDFS推理)
建立一个没有推理功能的本体模型:OntModel m = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
OntModelSpec中定义了许多与OWL语言,存储模型以及推理器的相关设置。
可以从不同的本体文件document中读入本体模型,这些模型中有一个基本模型,这个模型可以将几个本体模型集合起来;对这些模型的管理是分开的。获取基本模型: Model base= myOntModel.getBaseModel();



本体文件管理者(document manager)
每个本体模型都有一个相关的文件管理器,支持本体文件以及相关的处理过程。有一个全局的文件管理器,用来被整个本体模型使用。可以使用OntDocumentManager.getInstance()来取得管理器的引用。也可以分别对每个模型设置文件管理器:
OntDocumentManager mgr = new OntDocumentManager();
// set mgr's properties now
... some code ...
// now use it
OntModelSpec s = new OntModelSpec( OntModelSpec.RDFS_MEM );
s.setDocumentManager( mgr );
OntModel m = ModelFactory.createOntologyModel( s );

---------------------------------------------------------------
组合本体文件和importing过程
文件管理器有很多很多的配置参数,有两种自定义方法。第一种,通过代码设置文件管理器实例引用的参数修改配置。第二种,通过manager policy文件修改。


ModelMaker:创建存储需求
对于新创建新添加的本体,Jena定义了model maker来允许不同的模型存储方式(内存的,文件的,数据库的)。新的model maker可以使用ModelFactory来创建。
当基本模型刚创建时,需要使用maker来分配存储空间,当新的模型加入时,需要为他们开辟存储。所以,有两种ModelMaker,一种的是base model maker,一种是imports model maker。


在Jena内部,使用Graph来作为基础的数据结构,而应用的代码常常总会引用model而不是graphs。Model是Graph的一种封装,提供了一种方便的编程接口(Model)来管理简单的易管理的内部数据结构(Graph)。应将Model视作RDF和本体数据的容器。

控制imports过程
默认的,调用reas()时,imports别的本体是自动进行的。如果不希望imports,在调用read()函数前使用文件管理器的setProcessImports(False)方法。也可以在policy文件中设置。可以选择性忽略某些imports:addIgnoreImport( String uri )


管理文件引用
使用本体工作的一个优点是可以重用其他的本体,importing别人已经发布的本体进我们自己的本体。OntModel可以自动地引用这些本体从他们已经发布的URL中。这会使应用启动时有一个延迟。可能会因为网络或者文件移动等等,导致加载失败。为避免此种情况,可以使用Jena的FileManager来管理本地的间接定向,试图从一个Url里导入一个文件。
这里的意思就是,预先从一个网上URL里下载好别人的本体,然后将它重定向成本地的一个目录URL,在本体加载的时候,虽然还是原来的URL,但是实际访问的却是本地的URL目录下的文件。




明确前缀
一个model维护者一系列的URI前缀
import进的model可以被放入文件管理器的缓存(cache).


---------------------------------------------------
一个通用的本体类型:OntResource
本体API中的代表本体的各种类值的类拥有一个共同的超类 OntResource. 可以把这些类所共享的功能放入OntResource中,对于一些通用的方法可以返回方便的值。java类OntResource继承了Jena的RDF的Resource接口,因而任何接受一个resource或者一个RDFNode的方法,可以接受OntResource,或者,其他的本体值。


一些通过方法所表达的共有的本体属性资源在OntResource中,如下:
OntResource的一些属性和方法
属性:versionInfo(资源的版本或历史),comment(资源描述),label(人可读的标签),seeAlso(其他的web位置可以获取相关信息),isDefinedBy,sameAs,differentFrom
方法:     add<property> 为给定的属性添加值
               set<property>  设置属性值
list<property>  返回一个迭代器,遍历属性的值
get<property>  返回一个属性的值
has<property>  返回true/false
remove<property>删除属性的值


OntResource定义了许多通用的工具方法。例如,对于一个给定资源的属性,有多少个取值,可以调用getCardinality(Property p);从一个本体中删除某个资源可以调用remove(),这个的影响是,将会删掉每一个与提到这个资源作为subject或者object的声明语句(statement);为了获取一个属性的取值,可以调用getPropertyValue(Property p),设置属性值调用setProperty(Property p,RDFNode value);一个命名属性列举其取值可以使用listPropertyValues();删除属性可以使用removeProperty(),添加属性使用addProperty();
最后,OntResource类提供了一些方法来list,get,set资源的rdf:type属性,这个值表示,这一个资源属于那个类(在RDF/OWL中,一个资源可以一次属于好多类)。rdf:type属性是许多本体语言的语义模型里定义的推演规则的一种。因此,listRDFTypes()方法的返回值将不仅仅取决于依赖于本体模型的推理器(reasoner)。
对于一些任务,获取一个资源的所有的RDF types的列表是我们需要的。对于另一些,则不需要。这就涉及到断言类型(asserted types)和推理类型(inferred types)。所谓的断言类型就是在语句中声明过的。而其他的一切都是推理类型。

listRDFTypes()                 // assumes not-direct
listRDFTypes( boolean direct ) // if direct=true, show only direct relationships


-------------------------
本体类(OntClass)以及基本的类表达式
类是本体的最基本的构建模块。一个简单的类在Jena里通过一个OntClass的对象来表示。一个本体的类是一个RDF资源的一个方面。将一个普通的RDF资源(convert)为它的类方面可以获得一个本体类。假设,m是一个本体模型OntModel,并且已经加载了本体文件,NS表示本体的名字空间。
Resource r=m.getResource(Ns+"Paper");
OntClass paper=r.as(OntClass.class);
可以简单地以OntClass paper = m.getOntClass(NS+"Paper");来代替。

可以创建一个本体类通过 m.getOntClass(NS+“Paper”);方法
也可以创建一个匿名类 m.getOntClass();  匿名类就是没有URI描述的类。在RDFS中意义不大。

一旦获取了本体的类对象,就可以开始使用OntClass中的方法来操作它。一个类的属性(attributes)可以以OntResource那个同样的方式来操作。有一系列的set/get/add/test/list/remove方法和返回值。
本体类的属性(Properties)通过java类OntClass的属性(attributes)来操作。
OntClass的常用属性:
subClass(子类)表示了本体的subclassof属性(subject) domain
superClass(超类)表示了本体的对其他类的subclassof属性(Object) range
equivalentClass
disjointWith(不相交)


listSubClasses()和listSuperClasses()等方法获取上面的属性


OntClass的常用方法:可以操作本体类的实例
listInstances() 返回一个iterator包含了那些rdf:type值为这个类的实例
listInstances(boolean direct) direct=true返回直接实例
createIndividual(String URI)创建一个实例。即向本体模型加入一个资源,它的断言rdf:type是这个本体类。
dropIndividual(Resource individual) 删除关于本体类和实例之间的联系,并不会删除实例资源本身。如果要删除,调用remove()方法。
判断(test)一个类是不是本模型的root类(没有超类),调用isHierarchyRoot()方法。

-------------------------
本体属性(Property)
在一个本体中,属性表示了资源之间以及资源和数据值之间关系的名称。
它对应着一个逻辑表达的谓词(predicate)。
Jena中有一系列的java类允许操作在本体模型中表达的类。
本体模型中的一个属性(property)是core Jena API类Property的一个拓展。
代表了本体属性的共同的API超类是OntProperty。它也有一系列的方法来获取属性和方法。
java类属性
subProperty (表示一个子属性)  q subPropertyof p: A p B -> A q B 
superProperty(父属性)
domain(表示,组成这个属性的domain的类,多个domain值组成一个合集the class of value the property maps from(箭头起源的))
range(表示,组成这个属性的range的类,多个range值组成一个合集)(the class of value the property maps to(箭头指向的))
equivalentProperty(表示,与这个属性相同的类属性)
inverse(表示这个属性的逆)q inverseof p: A p B —> B q A;

对象属性和数据类型属性
OWL从基本的RDF属性中提炼了两种子类型:object properties和datatype properties。它们之间的区别在于对象属性的range只能是实例(Individuals),而数据类型属性只能是具体的数据原义(concrete data literals)。一些OWL的推理器可以探索它们之间的不同来对本体进行有效的推理。OWL也加入了一个标注属性,它没有语义含义,对于标注本体文件比较有用。在Jena中,ObjectProperty,DatatypeProperty以及AnnotationProperty都是OntProperty的子类。


Functional properties(函数属性)
OWL允许对象属性和数据类型属性是功能性的(Functional),也就是说,对于一个给定的domain里面的实例,range的值将总是一样的(函数的定义域和值域一一对应关系)。例如一个functional属性father,一个实例:jane有一个father :james和:jim,那么推理器就会推出:jim和:jane是一个实例。
函数属性通过本体属性对象的FunctionalProperty来表现。如果一个属性声明为functional(使用isfunctional()来测试),asFunctionalProperty()方法返回一个函数属性的方面,一个非函数的属性可以通过convertToFunctionalProperty()方法转化成函数属性。


其它属性类型
TransitiveProperty表示传递(过渡)属性,A p B,B p C—>A p C
SymmetricProperty表示如果p是对称的属性,A p B —> B p A
InverseFunctionalProperty表示对于给定的range元素,domain值是唯一的。
由于所有的属性都是RDFNode对象,所以支持as()方法,可以使用as()方法讲一个对象属性侧面转化为传递属性侧面。OntProperty类有一系列的方法支持直接的转化。asXXXProperty()方法返回一个XXXProperty对象。对于不支持转换的RDF模型,这些方法将抛出一个ConversionException异常。convertToXXXProperty()方法将添加额外的信息(rdf:type 声明)来支持转换的成功。
------------------------
更复杂的类表达式
上面介绍了处理基本的命名的类。这些是RDFS中唯一可用的类描述;然而在owl中,有一系列的额外的类表达类型,它们可以提供对于概念的更加丰富的描述。有两种主要的额外的类表达式的种类:约束和布尔表达式。


1、约束类表达
一个约束定义一个类,通过引用与这个类的成员一致的实例的属性,然后在这个属性上添加约束。目前OWL定义了有六种约束类型:
has value 约束属性仅有那个给定的的值。
all values from 约束属性的所有值,如果有的话,是给定的类的成员。
some values from 这个属性有至少一个值,是给定类的成员。
cardinality(基数)属性有确定的n个值,n是某个正整数。
min cardinality (最小基数) 属性有至少n个值
max cardinality (最大基数) 属性有至多n个值

Jena提供了一系列的方法支持创建restrictions,从一个模型中提取它们。首先,可以通过URI从一个本体模型中提取出一个普通的约束。
Restriction r = m.getRestriction(URI);  //通过URI来获取Restriction
Restriction r = m.createRestriction(Property p);   //通过为约束传入指定的属性来创建约束
Iteratior<Restriction> i = m.listRestrictions();  //列出本体模型中的约束,,然后可以搜索需要的约束
Iteratior<Restriction> i = p.listReferringRestrictions();   //列出包含有属性p的约束

一个通用的约束可以被转换成上述那六种具体类型的约束。
r.asXXXX();
r.convertToXXXXRestriction()
创建一个具体类型的约束: r = m.createXXXXRestriction(null,p,c);

2、布尔类表达
and/or/not


在构建和使用boolean class expression之前,我们先讨论一下列举(list)
List expressions
RDF最初有三类容器类型(Seq、Alt、Bag),它们都是开放形式(没有固定的元素数目)。后来加入的List

Intersection ,union,complement class expressions
分别表示交,并,补 的类表达式


枚举类(Enumerated classes)
OWL允许的最后一种类表达式就是枚举类。一个本体类拥有一系列的实例。枚举类就是在类定义的时候,显式地将类的实例也定义了,例如三原色这个类的实例,就只是红绿蓝这三种颜色而已。
Jena中的枚举类的创建与其他的类相似。构成枚举的值的集合,用一个RDFList来表达。
DataRange与枚举类很相似,不过,DataRange的成员是语义值,比如整数,日期,字符串等。

列举类(Listing classes)
有一系列的listXXXClasses()方法,列举各种类,返回一个ExtendedIterator<XXXClass>迭代器
迭代器在hasNext()方法返回false时,会自动close掉,如果不迭代到他的最后,要显式地调用close()方法关闭迭代器,以释放资源。

------------------------------
本体实例(Instances or individuals)
两种创建类实例的方法:
1、通过model创建
OntClass c = m.createClass(NS+"SomeClass");
Individual ind0 = m.createIndividual(NS+"ind0",c);
2、通过本体类创建
Individual ind1 = c.createIndividual(NS+"ind1");


-------------------------------
本体元数据(Ontology meta-data)
在OWL而不是RDFS中,关于本体自身的元数据封装作为类owl:Ontology的实例的属性。
按惯例,实例的URI可以是URL或者web地址,或者本体文件本身。在xml序列化中,这个是
<owl:Ontology rdf:about=""></owl:Ontology>
可以向这个本体实例添加属性的元数据声明。java对象Ontology代表了这个特殊的实例,可以使用标准的add,set,get,list,test,delete等操作属性。
baclwardCompatibleWith 兼容的之前本体版本
incompatibleWith 不兼容的本体的之前版本
priorVersion 这个本体的之前版本
imports 这个本体中所包含的本体的定义

除了这些属性,本体元素也包含一些共有的元数据属性,比如comment,Label,version information等

Jena API中,这些本体的元数据属性可以通过Ontology接口来获取。如果我们希望获取这个本体所import的本体的URI,首先我们应该获取到代表这个本体自己的资源(resource):
Ontology ont =m.getOntology(base);//通过base URI获取自身本体

Iterator<String> it = ont.listImportedOntologyURIs(); //获取导入的本体URI


ref-link:  http://jena.apache.org/documentation/ontology/#working-with-persistent-ontologies



0 0
原创粉丝点击