以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 RSS/FOAF/Dublin Core/CIM/PRISM/Gene Ontology 』  (http://bbs.xml.org.cn/list.asp?boardid=3)
----  使用 Jena API 处理 RDF  (http://bbs.xml.org.cn/dispbbs.asp?boardid=3&rootid=&id=6475)


--  作者:admin
--  发布时间:4/5/2004 6:13:00 PM

--  使用 Jena API 处理 RDF
http://cmpp.linuxforum.net/XML/rdf.html

使用 Jena API 处理 RDF

作者:Joe Verzulli
发表时间:2001年5月23日
原文链接:http://www.xml.com/pub/a/2001/05/23/jena.html
译者:dlee
翻译时间:2001年5月26日

对于 RDF (资源定义框架) 的兴趣正在日渐增长,很多用于处理 RDF 的工具和开发库已经被开发出来。这篇文章描述了一个这样的开发库,Jena,用于处理 RDF 的一套 Java API,它也是一个实现这套 API 的开放源码软件的名字。

什么是 RDF?

XML 非常灵活,它允许信息以很多种不同的方式来编码。如果使用有意义的标记,对于人来确定一个 XML 字符串的含义就会相对容易。尽管如此,对于程序来说确定一个 XML 字符串的含义仍然是困难的,因为程序并不懂得英文的标记名。DTD 和 XML Schema 对于这一问题并非真正有帮助,它们只是允许一个程序来验证一个 XML 字符串是否符合某个规则集合。
RDF (RDFMS ,Bray, Ogbuji,SWARDF) 是一个以一种允许程序懂得文档意图表现的含义的方式来表现信息的模型和 XML 语法。它建立在一个 statement,即具有形式{predicate, subject, object} 的一个三元组的概念之上。对于一个三元组的解释是 < subject> 有一个属性 < predicate>,属性值是 < object>。statement 的例子是 {numberOfHits, http://www.foo.com/index.html, 3000} 和 {title, http://bookstore.com/book12, "The Connoisseur's Guide to the Mind"}。在 RDF 中一个 总是一个以 URL 来命名的资源,这个 URL 有一个可选的锚 id。< predicate> 是资源的一个属性,< object> 是资源属性的值。

考虑下面的三元组 (这里 dc 前缀的含义是 Dublin Core)

{dc:Publisher, http://www.w3.org, "World Wide Web Consortium"}
{dc:Title, http://www.w3.org, "W3C Home Page"}

这些三元组能够被图形化地表示为这样

[graph1]

在这个图形中弧线被标记为 predicate。每条弧线从一个代表 subject 的节点出发,终止于一个代表 object 的节点。三元组和图形是同一 RDF 数据模型的两种不同表示。

对于这个模型也有一个 XML 的表示。RDF 要求不同类别的语义信息 (例如,题目,属性和值) 被放置在 XML 中指定的地点。 读取一个 XML 编码的 RDF 程序随后可以确定是否一个特定的元素或属性指示一个主题,一个属性或一个属性的值。

Jena API

Jena 由 HP 公司的 Brian McBride 开发,起源于早些时候 SiRPAC API 的工作。Jena 允许你来解析,创建和查询 RDF 模型。

Jena 定义了很多的接口来访问和处理 RDF statement,如下图所示

[image2]

RDFNode 接口为所有的可以作为一个 RDF 三元组一部分的元素提供了一个公共的基础。Literal 接口表示字面值,例如 “red fish” 或 225,可以被用来作为 {predicate, subject, object} 三元组中的 < object>。Literal 接口提供了将字面值转换为诸如 String,int 和 double 这样的 Java 类型的访问方法。

实现 Property 接口的对象可以作为 {predicate, subject, object} 三元组中的 < predicate>。

Statement 接口表示一个 {predicate, subject, object} 三元组。它也可以被用来作为一个三元组中的 < object>,因为 RDF 允许 statement 嵌套。
实现 Container,Alt,Bag 或 Seq 的对象可以作为三元组中的 < object>。

使用 Jena 解析 RDF

一个 RDF 非常有用的领域是在 Web 页面中嵌入元数据。这个 RDF 能够被编码为嵌入在 XHTML 页面中的 XML。
一个了解 RDF 的搜索引擎能够使用这些元数据来给出比一个仅仅靠关键字匹配的搜索引擎给出的更加关联的结果。一个了解 RDF 的搜索引擎爬虫能够使用 Jena 来解析 RDF,这由 Model 接口里的 read() 方法来完成,就象以下代码显示的那样(为清晰起见,例外处理已被省略)

File f;
FileReader fr;
Model model;

f = new File("C:\\test1.html");
fr = new FileReader(f);
model = new ModelMem();
model.read(fr, RDFS.getURI());

在这个例子中,C:\test.html 是一个有 RDF 在 元素中的 XHTML 文件。Jena 自动提取 RDF 并忽略 XHTML 的其余部分。解析的结果是一个包含文件中三元组的 RDF 模型。这个模型随后可以被查询。
代码片段中声明之后的前两个语句将 fr 设置为一个与 C:\test.html 相关联的 FileReader。model 被设置为一个 ModelMem 类的实例。ModelMem 是一个 Jena 提供的类,实现 Model 接口,使用主内存来存储模型。其它的实现也是可能的;例如,你可以创建一个基于事务处理数据库的实现。

从一个模型中得到所有的 Statements

一旦一个搜索引擎爬虫创建了一个包含一个 Web 页面元数据的 RDF 模型,它需要添加每个三元组到它的索引中,这样以后搜索就可以找到这个页面。这可以由 Model 接口的 listStatements() 方法来完成。listStatement() 返回一个 StmtIterator 来迭代模型中的每个 statement。它可以象这样来使用

Model model;
StmtIterator iter;
Statement stmt;
.
.
.
iter = model.listStatements();
while (iter.hasNext()) {
stmt = iter.next();
// Now use
}

Statement 接口提供了访问 satement 中 predicate,subject 和 object 的方法,如下所示

Property predicate;
Resource subject;
RDFNode obj;
Statement stmt;
.
.
.
subject = stmt.getSubject();
System.out.println("Subject = " + subject.getURI());
predicate = stmt.getPredicate();
System.out.println("Predicate = " +predicate.getLocalName());
obj = stmt.getObject();
System.out.println("Object = " + obj.toString());

添加 Statement 到一个模型

并非所有应用程序都从 XML 或 XHTML 文件中读取 RDF,很多需要创建基于用户输入或其它数据的 RDF Statement。考虑一个用来维护 email 消息,浏览器书签和日历条目的可查询档案库的 RDF 个人信息管理器。当程序接收到一个新的 email 消息时,它能够提取出发送者和主题,为其创建 RDF 三元组。它也允许用户输入关于消息讨论的主题的信息,并创建包含该主题的 RDF 三元组。

下面的代码演示了 Jena 怎样能够用来在一个模型中创建三元组

Model model;
String namespace = "http://www.test.com";
.
.
.
model.createResource("http://www.foo.com/boats#sailboat")
.addProperty(model.createProperty(namespace, "length"), 25)
.addProperty(model.createProperty(namespace, "color"), "teal");

这段代码添加了下面的 statements 到模型中

{x:length, http://www.foo.com/boats#sailboat, 25}
{x:color, http://www.foo.com/boats#sailboat, "teal"}

这里 x 是一个名域前缀,对应于名域的 URI http://www.test.com

查询模型

一旦一个 RDF 模式被创建,我们需要一种方法来查询它,例如,考虑一个包含 RDF 元数据的旅游 FAQ。假设我们想找到所有与非洲旅行有关的问题,换句话说我们希望找到在模型中所有具有形式 {destination, res, Africa} 的 res 的值。下面的代码显示怎样完成这件事。它任意假设属性的目的地是在一个 http://foo.org 的名域中。

Model model;
Resource r;
ResIterator resourceIter;
.
.
.
resourceIter = model.listSubjectsWithProperty(
model.createProperty("http://foo.org/destination"),
"Africa");
while (resourceIter.hasNext()) {
r = resourceIter.next();
System.out.println("Resource " + r.toString() +
" is about travel to Africa");
}

listSubjectsWithProperty(p, v) 为任何 < subject> 查找所有的 {p, < subject>, v} 形式的三元组。它返回一个迭代匹配的三元组对象。

哪里能够得到 Jena

Jena 可以从这里下载 http://www.hpl.hp.co.uk/people/bwm/rdf/jena/download.htm 。下载文件包括一些例子,JavaDoc,源代码和 jar 文件。

致谢

感谢 Brian McBride 为这篇文章的草稿所写的富有帮助的评论和创建了 Jena。


--  作者:tomcat
--  发布时间:4/6/2004 10:06:00 AM

--  
感谢admin!!
--  作者:wwwsin88
--  发布时间:4/14/2004 8:30:00 AM

--  
长知识呀.
--  作者:jcp0326
--  发布时间:5/1/2004 4:24:00 PM

--  
怎样使用JENA啊?请指点一下
--  作者:crowmuth
--  发布时间:5/8/2004 2:08:00 PM

--  
文章有点老了...

Jena更新很快,不过基本用法差不多,楼上的看看文中的例子就行了


--  作者:shrink
--  发布时间:8/2/2004 8:13:00 PM

--  
jena的命名空间怎么修改呢?
--  作者:dianadai
--  发布时间:12/2/2004 7:49:00 PM

--  
请问Jena怎么读取owl?
--  作者:blackeyes
--  发布时间:1/3/2005 8:24:00 PM

--  
我不知道jana是什么东西呀,它是干什么用的呀
--  作者:liuzane
--  发布时间:3/20/2005 10:29:00 AM

--  
以下是引用dianadai在2004-12-2 19:49:15的发言:
请问Jena怎么读取owl?


同样的问题
--  作者:blackmatrix
--  发布时间:4/5/2005 5:11:00 PM

--  
owl文件属于ontology,需要用到OntModel。参照Jena的ontology api文档
W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
3,515.625ms