在 Myeclipse 中实现 Jena
可以在 Jena 的主页(http://jena.sourceforge.net/downloads.html)下载 Jena 的最新版本,目前是 Je
na2.4 版本。Jena 是 Java API,所以需要 Java 运行环境。本文使用的是 jdk1.5.0_04 和 Eclipse3.2。
1)将下载的 Jena-2.4.zip 解压到任意路径,解压之后生成 Jena2.4 文件夹,将 Jena2.4\lib 下的 jar 文
件全部加入 CLASSPATH,这样就可以在任意的 Java 编辑器中调用 Jena API 了。在解压目录下有一个 test.
bat 文件,用于配置的测试。在控制台运行此程序,如果你的配置正确,测试将顺利完成。
2)如果使用 Eclipse,则可以通过修改工程的 Java 创建路径的方法导入 Jena jar 文件。在 Eclipse 下创
建 Java 工程(eg:OWL_SQL.java),右健单击工程名字,选择“属性/Properties”,在打开的对话框中
选择“Java 创建路径/Java Build Path”,在右边标签中选择“库/Libraries”,之后选择“添加外部文
件/Add Extenal JARs”,找到 Jena2.4\lib 目录下的所有 jar 文件并将其添加到工程。这样就可以运行 J
ean 文档中的例子了。
3)在 Eclipse 中用同样的方法导入 mysql-connector-java-5.0.8-bin.jar 到工程 OWL_SQL.java 中。
import java.io.*;
import java.sql.SQLException;
import com.hp.hpl.jena.db.*;
import com.hp.hpl.jena.rdf.model.*;
public class OWL_SQL1{
public static final String strDriver ="com.mysql.jdbc.Driver"; // path of driver c
public static final String strURL ="jdbc:mysql://localhost:3306/avan"; // URL of d
lass
atabase
public static final String strUser ="root"; // database user id
public static final String strPassWord ="root"; // database password
public static final String strDB="MySQL"; // database type
public static void main(String[] args){
try{// 创建一个数据库连接
Word, strDB );
IDBConnection conn = new DBConnection ( strURL, strUser, strPass
// 加载数据库驱动类,需要处理异常
try{
Class.forName(strDriver);
}catch(ClassNotFoundException e) {
System.out.println("ClassNotFoundException, Driver is
not available...");
}
// 使用数据库连接参数创建一个模型制造器
ModelMaker maker = ModelFactory.createModelRDBMaker(conn);
// 创建一个默认模型,命名为 MyOntology
Model defModel = maker.createModel("TNB");
// 准备需要存入数据库的本体文件,建立输入文件流
FileInputStream inputStreamfile = null;
try {
TNB.owl");
");
File file = new File("D:\\Program Files\\Protege_3.1\\
inputStreamfile = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("Ontology File is not available...
}
InputStreamReader in = null;
try {
in = new InputStreamReader(inputStreamfile, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 读取文件
defModel.read(in,null);
// 关闭输入流读取器
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
// 执行数据转换,将本体数据存入数据库
defModel.commit();
// 关闭数据库连接
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}catch(RDFRDBException e){
System.out.println("Exceptions occur...");
}
}
}
二,Jena Ontology API
Jena2.4 的 Ontology API 包含在 ontology 包(com.hp.hpl.jena.ontology)中,可以在目录\\Jena-2.4\
src\com\hp\hpl\jena\ontology 下查看所有程序的代码,Jena 本体部分的说明网页是\\Jena-2.4\doc\on
tology\index.html,本部分内容以及程序的编写主要参考这两个文档。
在语义网上有很多表示本体信息的本体语言,其中表达能力最强的是 OWL,OWL 按复杂程度分为 OWL Full、
OWL DL 和 OWL Lite 三个版本。其他的本体语言还有 RDFS、DAML+OIL。Jena Ontology API 为语义网应用
程序开发者提供了一组独立于具体语言的一致编程接口。
Jena 提供的接口本质上都是 Java 程序,也就是.java 文件经过 javac 之后生成的.class 文件。显然,cla
ss 文件并不能提示本体创建使用的语言。为了区别于其他的表示方法,每种本体语言都有一个自己的框架
(profile),它列出了这种语言使用的类(概念)和属性的构建方式和 URI。因此,在 DAML 框架里,对
象属性()的 URI 是 daml:ObjectProperty,而在 OWL 框架里却是 owl:ObjectProperty。RDFS 并没有定义
对象属性,所以在 RDFS 框架里,对象属性的 URI 是 null。
在 Jena 中,这种框架通过参数的设置在创建时与本体模型(Ontology Model)绑定在一起。本体模型继承
自 Jena 中的 Model 类。Model 允许访问 RDF 数据集合中的陈述(Statements),OntModel 对此进行了扩展,
以便支持本体中的各种数据对象:类(classes)、属性(properties)、实例(个体 individuals)。
本部分简单介绍要用到的几个 java 类或者接口。
1.本体模型 OntModel
本体模型(OntModel)是对 Jena RDF 模型的扩展(继承自 RDF 模型),提供了处理本体数据的功能。使用
Jena 处理本体首先就是要建立一个本体模型,之后就能够通过本体模型中所定义的方法操作模型,比如导
入子模型()、获取模型中本体的信息、操作本体属性以及将本体的表示输出到磁盘文件等等。Jena 通过
model 包中的 ModelFactory 创建本体模型,ModelFactory 是 Jena 提供用来创建各种模型的类,在类中定
义了具体实现模型的成员数据以及创建模型的二十多种方法。一个最简单的创建本体模型的语句如下:
OntModel ontModel = ModelFactory.createOntologyModel();
该语句不含参数,应用默认设置创建一个本体模型 ontModel,也就是说:它使用 OWL 语言、基于内存,支
持 RDFS 推理。可以通过创建时应用模型类别(OntModelSpec)参数创建不同的模型,以实现不同语言不同
类型不同推理层次的本体操作。例如,下面的语句创建了一个使用 DAML 语言内存本体模型。直观地讲,内
存模型就是只在程序运行时存在的模型,它没有将数据写回磁盘文件或者数据库表。
OntModel ontModel = ModelFactory.createOntologyModel( OntModelSpec.DAML_MEM );
更多类型设置可以参照 OntModelSpec 类中的数据成员的说明。
我们所使用的本体是从 OWL 文件获得的,也就是说,是从磁盘读取的。读取的方法是调用 Jena OntoModel
提供的 Read 方法。例如
ontModel.read("file:D:/temp/Creatrue/Creature.owl");
就是读取位于 D 盘相应目录下的 Creature.owl 文件以建立本体模型。Read 方法也有很多重载,上面调用
的方法以文件的绝对路径作为参数。其他的方法声明如下
read( String url );
read( Reader reader, String base );
read( InputStream reader, String base );
read( String url, String lang );
read( Reader reader, String base, String Lang );
read( InputStream reader, String base, String Lang );
2.文档管理器 Document manager
本体文档管理器(OntDocumentManager)是用来帮助管理本体文档的类,它包含了导入本体文档创建本体
模型、帮助缓存下载网络上的本体等功能。每个本体模型都有一个相关联的文档管理器。在创建本体模型
时,可以创建独立的文档管理器并作为参数传递给模型工厂(ModelFactory)。文档管理器有非常多的配
置选项,基本可以满足应用的需求。首先,每个文档管理器的参数都可以通过 Java 代码来设置(注:Ont
DocumentManager 有五种重载的构造函数)。另外,文档管理器也可以在创建的时候从一个 RDF 格式的策
略文件读取相应设定值。
下面的例子创建一个文档管理器并将它与以创建的本体模型关联。
OntModel m = ModelFactory.createOntologyModel();
OntDocumentManager dm = m.getDocumentManager();
3.接口 OntClass
这个接口中定义了本体中与概念(也就是类 Class)相关的操作,通过 OntModel 中的 listClasses()便可
以返回模型中的所有概念组成的迭代器(Iterator),然后调用 OntClass 的各种方法具体进行具体操作。
OntoClass 对概念之间的各种关系都有相应的定义方法,典型的有添加子类、添加约束、创建互斥概念、
迭代返回某种类型的概念以及相关的逻辑判断等等。
第四部分的例子主要是应用这个类的方法。
4.基本本体类型 OntResource
所有本体 API 中用于表示本体的类继承自 OntResource,这样就可以在 OntResource 中放置所有类公用的
功能,并可以为一般的方法设置通用的返回值。Java 接口 OntResource 扩展了 Jena 的 RDF 资源接口,所
以任何可以接受资源或者 RDFNode 的方法都可以接受 OntResource,并且也就可以接受任何其他本体值。
虽然这个类涵盖了涉及本体的所有类,在例子中并没有使用它。从 Jena Java Doc 可以获得它的详细信息。
例子的主要代码如下列出。
// 创建使用 OWL 语言的内存模型
OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
ontModel.read("file:./Creature.owl"); // 读取当前路径下的文件,加载模型
// 定义一个类作为模型中 Animal 类的等等价类,并添加注释
OntClass cls = ontModel.createClass(":DongwuClass");
cls.addComment("the EquivalentClass of Animal...", "EN");
// 通过完整的 URI 取得模型中的 Animal 类
OntClass oc = ontModel.
getOntClass("http://www.owl-ontologies.com/marine.owl#Animal");
oc.addEquivalentClass(cls); // 将先前定义的类添加为 Animal 的等价类
// 迭代显示模型中的类,在迭代过程中完成各种操作
for (Iterator i = ontModel.listClasses(); i.hasNext();) {
OntClass c = (OntClass) i.next(); // 返回类型强制转换
if (!c.isAnon()) { // 如果不是匿名类,则打印类的名字
System.out.print("Class");
// 获取类的 URI 并输出,在输出时对 URI 做了简化(将命名空间前缀省略)
System.out.println(c.getModel().getGraph().getPrefixMapping().shortForm(c.getURI()));
// 处理 Animal 类
if (c.getLocalName().equals("Animal")) { // 如果当前类是 Animal
System.out.println("
URI@" + c.getURI()); // 输出它的完整 UR
I
// 取得它的的等价类并打印
System.out.print("
Animal's EquivalentClass is "+ c.getEquivalentClass());
// 输出等价类的注释
System.out.println(" [comments:" + c.getEquivalentClass().getComment("EN")+"]");
}// 处理 Animal 结束
// 迭代显示当前类的直接父类
for (Iterator it = c.listSuperClasses(); it.hasNext();)
{
// 获取 URI
OntClass sp = (OntClass) it.next();
String str = c.getModel().getGraph().getPrefixMapping().shortForm(c.getURI())
String strSP = sp.getURI();
try{ // 另一种简化处理 URI 的方法
+ "'s superClass is " ;
str = str + ":" + strSP.substring(strSP.indexOf('#')+1);
System.out.println("
Class" +str);
}catch( Exception e ){}
} // super class ends
// 迭代显示当前类的直接子类
for (Iterator it = c.listSubClasses(); it.hasNext();){
System.out.print("
Class");
OntClass sb = (OntClass) it.next();
System.out.println(c.getModel().getGraph().getPrefixMapping()
.shortFo
+ sb.get
.shortFo
rm(c.getURI())+ "'s suberClass is "
Model().getGraph().getPrefixMapping()
rm(sb.getURI()));
}// suber class ends
// 迭代显示与当前类相关的所有属性
for(Iterator ipp = c.listDeclaredProperties(); ipp.hasNext();){
OntProperty p = (OntProperty)ipp.next();
System.out.println("
associated property: " + p.getLocalName());
}// property ends
}// anonymity ends
else {}// 是匿名类
}// for ends