关于jena的API说明

来源:互联网 发布:mac os 10.13 dmg 下载 编辑:程序博客网 时间:2024/05/16 01:19

 

本文来自:万能的天空
http://hi.baidu.com/wanneng/blog/item/7442af18c26bc00435fa41cd.html
Jena文档《An Introduction to RDF and the Jena RDF API》的译文
RDF和Jena RDF API入门
________________________________________
前言
本文是一篇对W3C的资源描述框架(RDF)和 Jena(一个Java的RDF API)的教程性介绍. 本文是为那些不熟悉RDF的, 以及那些通过建立原形可以达到最好学习效果的, 或是因为其他原因希望能快速操作Jena的程序员而写的. 我们假设读者在阅读本文前已具有一定的XML和Java知识.
如果读者在没有理解RDF数据模型的基础上就迅速进入操作阶段,往往会导致失败和失望. 然而,如果光学习数据模型又是十分枯燥乏味的, 并常常会导致曲折的形而上学的难题. 更好的学习办法是在理解数据模型的同时练习操作它. 可以先学习一点数据模型再动手试一试.然后在学习一点再试一试. 这样一来就能达到理论实践相结合的效果.数据模型本身十分简单,所以学习过程不会太长.
RDF具有XML的语法, 所以许多熟悉XML的人就会认为以XML语法的形式来思考RDF. 然而, 这是不对的. RDF应该以它数据模型的形式来被理解. RDF数据可是用XML来表示, 但是理解数据模型的重要性更在理解此语法重要性之上.
Jena API的一个运行例子, 包括本教程中所有例子的工作源代码都可以在http://www.hpl.hp.com/semweb/下载.
________________________________________
目录
1. 导言
2. 陈述Statements
3. RDF写操作
4. RDF读操作
5. Jena RDF 包
6. 操纵模型
7. 查询模型
8. 对模型的操作 
9. 容器Containers
10. 关于Literals和数据类型的更多探讨
11. 术语表
________________________________________
导言
资源描述框架是(RDF)是描述资源的一项标准(在技术上是W3C的推荐标准). 什么是资源? 这实在是一个很难回答的问题, 其精确的定义目前尚在争论中. 出于我们的目的, 我们可以把资源想象成任何我们可以确定识别的东西. 在本教程中,读者你本身就是一个资源, 而你的主页也是一个资源, 数字 1和故事中巨大的白鲸都是资源.
在本教程中, 我们的例子会围绕人们展开. 假设人们会使用VCARDS, 而VCARD将由RDF表示机制来描述. 我们最好把RDF考虑成由结点和箭头的形式构成的图. 一个简单的vcard在RDF中可能看起来是这样的:

资源John Smith在图中用椭圆表示, 并被一个统一资源定位符(URI) 所标识, 在本例中是"http://.../JohnSmith"). 如果你想要通过你的浏览器来访问这个资源的话,你很有可能会失败. 四月的愚人节笑话并不经得起考验, 相反如果你的浏览器把John Smith传递到你的桌面的话, 你才该感到惊讶. 如果你并不熟悉URI's的话, 你可以把它们想象成简单的陌生名字.
资源拥有属性(property). 在这些例子中, 我们对John Smith名片上出现的那些属性很感兴趣.图1只显示了一个属性,   John Smith的全名. 属性是由标有属性名的箭头表示的. 属性的名字也是一个URI, 但是由于URI十分冗长笨重, 所以图中将它显示为 XML qname的形式. 在':'之前的部分称为命名空间前缀并表示了一个命名空间. 在':'之后的部分称为局部名, 并表示在命名空间中的一个名字. 在写成RDF XML形式时, 属性常常以qname的形式表示, 这是一个在图形和文本中的简单的缩写方法. 然而, 严格地讲, 属性应该用 URI来标识. 命名空间前缀:局部名的形式是一种命名空间连接局部名的URI缩写. 当浏览器访问时, 用并没有强制属性的URI必须指向一些具体的事物.
每个属性都有一个值. 在此例中, 值为一个文本(literal), 我们现在可以把它看成一个字符串.文本在图中显示为长方形.
Jena是一个Java API, 我们可以用它来创建和操纵诸如上述例图的RDF图. Jena设有表示图(graph), 资源 (resource), 属性和文本(literal)的对象类. 表示资源, 属性和文本的接口分别称为Resource, Property, 和 Literal. 在Jena中, 一个图(graph)被称为一个模型并被Model接口所表示.
创建上述例图或称为上述模型的代码很简单:
// some definitions
static String personURI     = "http://somewhere/JohnSmith";
static String fullName     = "John Smith";

// create an empty Model
Model model = ModelFactory.createDefaultModel();

// create the resource
Resource johnSmith = model.createResource(personURI);

// add the property
johnSmith.addProperty(VCARD.FN, fullName);

这些代码先定义了一些常量, 然后使用了ModelFactory类中的createDefaultMode()方法创建了一个空的基于内存存储的模型 (Model 或 model). Jena还包含了Model接口的其他实现方式. 例如, 使用关系数据库的, 这些类型 Model接口也可以从 ModelFactory中创建.
于是John Smith这个资源就被创建了, 并向其添加了一个属性. 此属性由一个"常" ("constant")类VCARD提供, 这个类保存了在VCARD模式(schema)中所有定义的表示对象. Jena也为其他一些著名的模式提供了常类的表示方法, 例如是RDF和RDF模式,   Dublin 核心标准和DAML.
创建资源和添加属性的代码可以写成更紧凑的层叠形式:
Resource johnSmith =
         model.createResource(personURI)
             .addProperty(VCARD.FN, fullName);
这个例子的工作代码可以在Jena发布的材料的教程包中的Tutorial1中找到. 作为练习, 你自己可以获得此代码并修改其以创建一个简单VCARD.
现在让我们为vcard再增加一些更详细的内容, 以便探索更多的RDF和Jena的特性.
在第一个例子里, 属性值为一个文本. 然而RDF属性也可以采用其他的资源作为其属性值. 下面这个例子使用常用的RDF技术展示了如何表示John Smith名字的不同部分:

在这里我们增加了一个新的属性, vcard:N, 来表示John Smith名字的结构. 这个模型有几点有趣之处. 注意属性vcard:N使用一个资源作为起属性值. 同时注意代表复合名字的椭圆并没有URI标识. 它被认为是一个空白结点(blank Node).
创建此例的Jena代码也十分简单. 首先是一些声明和对空模型的创建.
// some definitions
String personURI     = "http://somewhere/JohnSmith";
String givenName     = "John";
String familyName   = "Smith";
String fullName     = givenName + " " + familyName;

// create an empty Model
Model model = ModelFactory.createDefaultModel();

// create the resource
//   and add the properties cascading style
Resource johnSmith
   = model.createResource(personURI)
         .addProperty(VCARD.FN, fullName)
         .addProperty(VCARD.N,
                       model.createResource()
                           .addProperty(VCARD.Given, givenName)
                           .addProperty(VCARD.Family, familyName));
此例的工作代码可以在Jena发布材料的教程包的Tutorial2中得到.
________________________________________
陈述
RDF模型中的每一个箭头表示为一个陈述(statement). 每一个陈述声明了关于某个资源的某个事实. 一个陈述有三部分组成.
主体, 也就是箭头的出发的资源.
谓词, 也就是标识箭头的属性.
客体, 也就是箭头所指向的那个资源或文本.
一个陈述有时也叫做一个三元组的原因就是它由三部分组成.
一个RDF模型(译者注: 指Jena中的接口Model)是由一组陈述所组成的. 在Tutorial2中, 每调用一次addProperty函数就会在模型中增加另一个陈述. (因为一个模型是由一组陈述组成的, 所以增加一个重复的陈述并不会产生任何意义.) Jena模型接口定义了一个 listStatements()方法, 此方法会返回一个StmtIterator类型的变量. StmtItor是Java中Iterator的一个子类型, 这个StmtIterator变量重复迭代了该接口模型中的所有陈述. StmtIterator类型中有一个方法nextStatement (), 该方法会从iterator返回下一个陈述. (就和next()返回的一样, 但是已将其映射为Statement类型). 接口 Statement提供了访问陈述中主体, 谓词和客体的方法.
现在我们会用使用那个接口来扩展Tutorial2, 使起列出所有的创建的陈述并将它们打印出来. 此例完整的代码可以在Tutorial3中找到.
// list the statements in the Model
StmtIterator iter = model.listStatements();

// print out the predicate, subject and object of each statement
while (iter.hasNext()) {
     Statement stmt       = iter.nextStatement();   // get next statement
     Resource   subject   = stmt.getSubject();     // get the subject
     Property   predicate = stmt.getPredicate();   // get the predicate
     RDFNode   object     = stmt.getObject();       // get the object

     System.out.print(subject.toString());
     System.out.print(" " + predicate.toString() + " ");
     if (object instanceof Resource) {
       System.out.print(object.toString());
     } else {
         // object is a literal
         System.out.print(" /"" + object.toString() + "/"");
     }

     System.out.println(" .");

因为一个陈述的客体可以是一个资源也可以是一个文本. getObject()方法会返回一个类型为RDFNode的客体, RDFNode是 Resource和Literal类共同的超类. 为了确定本例中的客体确切的类型, 代码中使用 instanceof来确定其类型和相应的处理.
运行后, 此程序回产生与此相似的输出:
http://somewhere/JohnSmith http://www.w3.org/2001/vcard-rdf/3.0#N anon:14df86:ecc3dee17b:-7fff.
anon:14df86:ecc3dee17b:-7fff http://www.w3.org/2001/vcard-rdf/3.0#Family   "Smith".
anon:14df86:ecc3dee17b:-7fff http://www.w3.org/2001/vcard-rdf/3.0#Given   "John" .
http://somewhere/JohnSmith http://www.w3.org/2001/vcard-rdf/3.0#FN   "John Smith".

现在你明白了为什么模型构建会更加清晰. 如果你仔细观察, 就会发现上面每一行都由三个域组成, 这三个域分别代表了每一个陈述的主体, 谓词和客体.   在此模型中有四个箭头, 所以会有四个陈述. "anon:14df86:ecc3dee17b:-7fff"是有Jena产生的一个内部标识符, 它不是一个URI, 也不应该与URI混淆. 它只是Jena处理时使用的一个内部标号.
W3C的RDF核心工作小组定义了一个类似的表示符号称为N-三元组(N-Triples). 这个名字表示会使用"三元组符号". 在下一节中我们会看到Jena有一个内置的N-三元组写机制(writer).