转载自 http://www.cnblogs.com/yuyd902/archive/2008/10/08/1306647.html
这篇文章是转贴《An Introduction to RDF and the Jena RDF API》的译文,并在适当的地方进行了标注,部分代码提供了jruby形式实现。
前言
本文是一篇对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/下载。
导言
资源描述框架(RDF)是描述资源的一项标准(在技术上是W3C的推荐标准)。什么是资源?这实在是一个很难回答的问题,其精确的定义目前尚在争论中。出于我们的目的,我们可以把资源想象成任何我们可以确定识别的东西。在本教程中,读者你本身就是一个资源,而你的主页也是一个资源,数字1 和故事中巨大的白鲸都是资源。
在本教程中,我们的例子会围绕人们展开。假设人们会使用VCARDS(VCARD称为电子商务卡片,主要用于记录通讯薄的联系人信息等,方面不同设备之间的数据交换——From Baidu ZHIDAO),而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);
require 'java'
module Java
include_package 'com.hp.hpl.jena.rdf.model'
include_package 'com.hp.hpl.jena.vocabulary'
PersonURI = "http://somewhere/JohnSmith"
FullName = "John Smith"
model = Java::ModelFactory.createDefaultModel
john_smith = model.createResource PersonURI
john_smith.addProperty VCARD::FN, FullName
end
这些代码先定义了一些常量,然后使用了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);
john_smith = \
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));
require 'java'
module Java
include_package 'com.hp.hpl.jena.rdf.model'
include_package 'com.hp.hpl.jena.vocabulary'
PersonURI = "http://somewhere/JohnSmith"
GivenName = "John"
FamilyName = "Smith"
FullName = GivenName + " " + FamilyName
model = Java::ModelFactory.createDefaultModel
john_smith = \
model.createResource(PersonURI)\
.addProperty(VCARD::FN, FullName)\
.addProperty(VCARD::N, \
model.createResource()\
.addProperty(VCARD::Given, GivenName)\
.addProperty(VCARD::Family, FamilyName))
end
此例的工作代码可以在Jena发布材料的教程包的Tutorial2中得到。