以文本方式查看主题 - 中文XML论坛 - 专业的XML技术讨论区 (http://bbs.xml.org.cn/index.asp) -- 『 Semantic Web(语义Web)/描述逻辑/本体 』 (http://bbs.xml.org.cn/list.asp?boardid=2) ---- Jena文档《An Introduction to RDF and the Jena RDF API》的译文 (http://bbs.xml.org.cn/dispbbs.asp?boardid=2&rootid=&id=20595) |
-- 作者:april1019 -- 发布时间:7/22/2005 10:35:00 AM -- 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 // create the resource // add the property 这些代码先定义了一些常量, 然后使用了ModelFactory类中的createDefaultMode()方法创建了一个空的基于内存存储的模型(Model 或 model). Jena还包含了Model接口的其他实现方式. 例如, 使用关系数据库的, 这些类型 Model接口也可以从ModelFactory中创建. // create an empty Model // create the resource // print out the predicate, subject and object of each statement System.out.print(subject.toString()); System.out.println(" ."); 现在你明白了为什么模型构建会更加清晰. 如果你仔细观察, 就会发现上面每一行都由三个域组成, 这三个域分别代表了每一个陈述的主体, 谓词和客体. 在此模型中有四个箭头, 所以会有四个陈述. "anon:14df86:ecc3dee17b:-7fff"是有Jena产生的一个内部标识符, 它不是一个URI, 也不应该与URI混淆. 它只是Jena处理时使用的一个内部标号. 应该有类似的输出: W3C的RDF规格说明书规定了如何用 XML的形式来表示RDF. RDF XML的语法十分复杂. 读者可以在RDF核心工作小组制定的RDF入门篇(primer)中找到更详细的指导. 但是不管怎么样, 让我们先迅速看一下应该如何解释上面的RDF XML输出 这会产生类似于Tutorial3的输出, 此输出会遵循N-三元组的规格. ________________________________________ // create an empty model // use the class loader to find the input file // read the RDF/XML file // write it to standard out ________________________________________ ________________________________________ 一般而言, 一个陈述的客体可以是一个资源或是一个文本. 所以此应用程序代码知道这个值一定是个资源, 就将类型资源映射到返回的对象上. Jena的目标之一是提供会返回值为特定类型的方法, 这样,应用程序就不必再做类型转换工作, 也不必再编译时做类型检查工作. 以上的代码片段也可以写成更方便的形式: 在这个例子中, 资源vcard只有一个vcard:FN属性和一个vcard:N属性. RDF允许资源有重复的属性, 例如Adam可能有超过一个的昵称. 让我们假设他有两个昵称: 正如前面所提到的那样, Jena将RDF模型表示为一组陈述, 所以在模型中新增一个与原有陈述有着相同的主体,谓词和客体的陈述并不会后什么作用. Jena没有定义会返回模型中存在的两个昵称中的哪一个. Vcard.getProperty(VCARD.NICKNAME)调用的结果是不确定的. Jena会返回这些值中的某一个, 但是并不保证两次连续的调用会同一个值. 此代码可以在Tutorial6中找到, 运行后会产生如下输出: 然而, 不幸的是, 我们现在正在使用的vcard模式并没有为vcard定义类型. 然而, 如果我们假设只有类型为vcard的资源才会使用vcard:FN属性, 并且在我们的数据中, 所有此类资源都有这样一个属性, 那么我们就可以像这样找到所有的vcard: 所有的这些查询方法不过是在原语查询方法model.listStatements(Select s)上稍做变化而已. 此方法会返回一个iterator, 该iterator会跌代模型中所有被s选中的陈述. 这个selector接口被设计成可扩展的, 但是目前, 它只有一个执行类,那就是com.hp.hpl.jena.rdf.model包中的SimpleSelector类. 在Jena中使用SimpleSelector是很少见的情况, 即当需要直接使用一个特定类而不是使用接口. SimpleSelector的构造函数带有三个参数: Selector selector = new SimpleSelector(subject, predicate, object) 这个示例使用了一个简洁的Java技术, 就是当创建此类的一个实例时重载一个内联的方法. 这里selects(…)方法会检查以保证全名以"Smith"做结尾. 重要的是要注意对主体, 谓语和客体的过滤是在调用selects(…)方法之前的执行的, 所以额外的测试只会被应用于匹配的陈述. 虽然在功能上它们可能是等同的, 但是第一种形式会列举出模型中所有的陈述, 然后再对它们进行逐一的测试. 而第二种形式则允许执行时建立索引来提供性能. 你可以在一个大模型中自己试试验证一下, 但是现在先为自己倒一杯咖啡休息一下吧. 和 让我们看一下这个代码的功能(完整的代码在Tutorial9中), 再看看会发生什么. // merge the Models // print the Model as RDF/XML petty writer会产生如下的输出: 即便你不熟悉RDF/XML的语法细节, 你仍然可以清楚的看见模型如同预期般被合并了. 我们可以在类似的方式下运算模型的交操作和差操作. 虽然bag容器的成员们被rdf:_1,rdf_2等等的属性所表示, 但是这些属性的顺序却并不重要. 即便我们将rdf:_1和rdf:_2的属性值交换, 但是交换后的模型仍然表示相同的信息. // select all the resources with a VCARD.FN property 如果我们将次模型输出可以看见它含有类似如下的成分: 这表示了Bag资源. 并会产生如下的输出: 本例的可执行代码可以在Tutorial10中找到. ________________________________________ // add the property // write out the Model 会产生: <rdf:RDF 如果两个文本被认为是相同的, 它们一定都是XML的文本或都是简单的文本. 另外, 它们两个要么都没有语言标签, 要么有相同的语言标签. 对简单的文本而言, 两者的字符串一定是相同的. XML文本的等同有两点要求. 第一, 前面提到的要求必须被满足并且字符串必须相同. 第二, 如果它们字符串的cannonicalization一样的话, 它们就是一样的.(译者注: 找不到cannonicalization中文的解释.). // add the property // write out the Model 产生的输出如下: 因为两个文本都是字符串"11", 所以只会有一个陈述被添加. |
-- 作者:admin -- 发布时间:7/22/2005 12:44:00 PM -- 赞!! |
-- 作者:tiansword -- 发布时间:7/29/2005 11:58:00 AM -- thanks! |
-- 作者:webcoolie -- 发布时间:8/5/2005 4:34:00 PM -- 太好了 |
-- 作者:ppf4 -- 发布时间:8/12/2005 6:24:00 PM -- Jana是HP公司的产品吗?在那可以下? |
-- 作者:jjojojj -- 发布时间:8/13/2005 11:09:00 AM -- 在这里可以下啊: http://nchc.dl.sourceforge.net/sourceforge/jena/Jena-2.2.zip |
-- 作者:yulin -- 发布时间:12/1/2005 9:39:00 PM -- thanks |
-- 作者:kyocica -- 发布时间:12/2/2005 3:47:00 PM -- 顶啊 |
-- 作者:ztszhang -- 发布时间:12/2/2005 7:00:00 PM -- 翻译得真好! 感谢! |
-- 作者:vole -- 发布时间:12/3/2005 1:50:00 PM -- 赞一个 |
-- 作者:yhl2016 -- 发布时间:12/4/2005 3:56:00 PM -- 谢谢! |
-- 作者:anew88 -- 发布时间:12/5/2005 4:33:00 PM -- 谢谢 |
-- 作者:instillwater -- 发布时间:12/6/2005 11:18:00 AM -- 赞! |
-- 作者:xirufeng -- 发布时间:12/12/2005 1:50:00 PM -- 谢谢楼主 |
-- 作者:xxiaoshilang -- 发布时间:12/13/2005 5:32:00 PM -- 非常感谢楼主 |
-- 作者:ld725725 -- 发布时间:12/15/2005 9:37:00 AM -- 多谢 |
-- 作者:fanfanfly -- 发布时间:12/15/2005 10:16:00 PM -- thanks |
-- 作者:dbjaje -- 发布时间:12/16/2005 4:10:00 PM -- 正在写论文,谢谢先,再看。 |
-- 作者:xuqinan -- 发布时间:12/20/2005 10:36:00 AM -- 顶!好 |
-- 作者:xinxindong -- 发布时间:12/20/2005 7:41:00 PM -- 太好了,谢谢! |
-- 作者:hzh_nc -- 发布时间:2/2/2006 9:04:00 AM -- 谢谢! 好东西 |
-- 作者:lbfeng -- 发布时间:2/8/2006 4:16:00 PM -- 非常感谢! |
-- 作者:yimuyunlang -- 发布时间:3/30/2006 9:29:00 PM -- 两个字:好人!比起那些只谈些概念的人不给实例的大虾好多了!很多大虾回答问题时不痛不痒,没有透明的说的让人一目了然的内容,说明大虾也只是忽悠理论,操作不行,自己肚中没有实例 |
-- 作者:Ambrosia -- 发布时间:3/31/2006 9:48:00 AM -- zan |
-- 作者:krazy -- 发布时间:3/31/2006 4:58:00 PM -- 谢谢共享 |
-- 作者:sunww1999 -- 发布时间:4/3/2006 11:45:00 AM -- 太感谢了!!! |
-- 作者:wolf_xjf -- 发布时间:4/7/2006 1:45:00 PM -- 谢谢! |
-- 作者:ruoxue -- 发布时间:4/12/2006 9:59:00 PM -- 不错谢谢 |
-- 作者:gwj_77_77_77 -- 发布时间:4/18/2006 10:35:00 AM -- 下了 多谢 |
-- 作者:cao_shan -- 发布时间:4/18/2006 4:17:00 PM -- april1019,你辛苦了!谢谢! |
-- 作者:jsarrn -- 发布时间:7/21/2006 9:38:00 PM -- 感谢! |
-- 作者:lixin_lichuan -- 发布时间:8/5/2006 2:25:00 PM -- 谢谢! |
-- 作者:fromtoz -- 发布时间:8/6/2006 9:08:00 PM -- good |
-- 作者:sophia-rener -- 发布时间:8/7/2006 2:29:00 PM -- 谢谢,正需要呢! |
-- 作者:paopao2008 -- 发布时间:8/27/2006 5:02:00 PM -- 真诚感谢中~ |
-- 作者:windancer2003 -- 发布时间:8/30/2006 12:22:00 AM -- 非常感觉! |
-- 作者:lqm -- 发布时间:8/30/2006 5:04:00 PM -- 好东东啊,我对RDF的入门理解,全部来自这篇文档啊!!!! |
-- 作者:skinner -- 发布时间:10/18/2006 2:00:00 AM -- 感谢万分 |
-- 作者:coco -- 发布时间:11/16/2006 9:04:00 PM -- 太好了.支持啊 |
-- 作者:zyq569 -- 发布时间:11/16/2006 9:42:00 PM -- 好文章,楼主好样的 |
-- 作者:zyq569 -- 发布时间:11/16/2006 9:44:00 PM -- 好文章,楼主好样的 |
-- 作者:ebookisok -- 发布时间:11/17/2006 11:17:00 AM -- 顶 |
-- 作者:cao_shan -- 发布时间:11/17/2006 12:56:00 PM -- 不错! |
-- 作者:Protege -- 发布时间:11/18/2006 6:34:00 PM -- 第一次顶,谢谢了 |
-- 作者:myxiangrong2000 -- 发布时间:11/19/2006 9:43:00 AM -- ding thanks! |
-- 作者:flyingFang -- 发布时间:11/21/2006 11:37:00 AM -- 大家好,我看不到楼主文章中的图。请问是只有我看不到么? 这篇文章的原文,大家可以给个链接么,谢谢。看到图的话,可能更利于理解。 谢谢 |
-- 作者:flyingFang -- 发布时间:11/21/2006 11:39:00 AM -- sorry。 刚刚自己找到原文了,可能大家都知道哈。我是新手,给同样是新手的同学,提供连接: http://jena.sourceforge.net/tutorial/RDF_API/ |
-- 作者:yongzhu -- 发布时间:11/21/2006 2:53:00 PM -- 这是精华啊 |
-- 作者:tacl202 -- 发布时间:11/30/2006 8:55:00 AM -- thanks |
-- 作者:tangling -- 发布时间:3/22/2007 10:23:00 AM -- 多谢!太棒了! |
-- 作者:eview -- 发布时间:3/25/2007 4:18:00 PM -- 哈哈, 看完了英文, 中文有点不适应了 |
-- 作者:ricky_lxl -- 发布时间:5/9/2007 11:22:00 PM -- 感谢!! |
-- 作者:zj007zj007 -- 发布时间:5/10/2007 9:11:00 AM -- 谢谢,收下了。 |
-- 作者:campushr -- 发布时间:5/11/2007 12:33:00 PM -- 向楼主表示感谢 |
-- 作者:bzbc -- 发布时间:9/28/2007 10:32:00 PM -- Jena 简介 Jena 简介 http://www.ibm.com/developerworks/cn/java/j-jena/ RDF 越来越被认为是表示和处理半结构化数据的一种极好选择。本文中,Web 开发人员 Philip McCarthy 向您展示了如何使用 Jena Semantic Web Toolkit,以便在 Java 应用程序中使用 RDF 数据模型。 “资源描述框架(Resource Description Framework,RDF)”最近成为 W3C 推荐标准,与 XML 和 SOAP 等 Web 标准并排。RDF 可以应用于处理特殊输入数据(如 CRM)的领域,已经广泛用于社会网络和自助出版软件(如 LiveJournal 和 TypePad)。 Java 程序员将越来越多地得益于具有使用 RDF 模型的技能。在本文中,我将带您体验惠普实验室的开放源代码 Jena Semantic Web Framework(请参阅 参考资料)的一些功能。您将了解如何创建和填充 RDF 模型,如何将它们持久存储到数据库中,以及如何使用 RDQL 查询语言以程序方式查询这些模型。最后,我将说明如何使用 Jena 的推理能力从本体推断模型知识。 本文假设您已经就图形、三元组和模式等概念方面对 RDF 比较熟悉,并对 Java 编程有基本的了解。 创建简单的 RDF 模型 我们从基本操作开始:从头创建模型并向其添加 RDF 语句。本节,我将说明如何创建描述一组虚构家庭成员之间关系的模型,如图 1 中所示:
图 1. 虚拟家庭树 将使用来自“关系”词汇表(请参阅 参考资料)的属性 siblingOf 、 spouseOf 、 parentOf 和 childOf 来描述不同的关系类型。为简单起见,家庭成员用来自虚构名称空间的 URI( http://family/ )进行标识。词汇表 URI 通常以 Jena 代码形式使用,所以将它们声明为 Java 常量会非常有用,减少了错误输入。 Schemagen 当您通过 Jena 的 API 来使用模型时,为模型词汇表中的每个属性定义常量非常有用。如果有词汇表的 RDF、DAML 或 OWL 表示,Jena 的 Schemagen 工具可以自动生成这些常量,使您的工作更加容易。 Schemagen 在命令行中运行,使用的参数包括模式或本体文件的位置、要输出的类的名称和 Java 包。然后可以导出生成的 Java 类,其 Property 常量用于访问模型。 还可以使用 Ant 将 Schemagen 作为构建处理的一部分来运行,保持 Java 常量类与正在变化的词汇表保持同步。 在 Jena 中,语句的主题永远是 Resource ,谓词由 Property 表示,对象是另一个 Resource 或常量值。常量在 Jena 中通过 Literal 类型表示。所有这些类型共享公共接口 RDFNode 。将需要四个不同的 Property 实例表示家庭树中的关系。这些实例使用 Model.createProperty() 创建。 将语句添加到模型中的最简单方法是通过调用 Resource.addProperty() 。此方法以 Resource 作为主题在模型中创建语句。该方法使用两个参数,表示语句谓词的 Property 和语句的对象。 addProperty() 方法被过载:一个过载使用 RDFNode 作为对象,所以可以使用 Resource 或 Literal 。还有有益过载,它们使用由 Java 原语或 String 表示的常量。在示例中,语句的对象是表示其他家庭成员的 Resource 。 通过使用三元组的主题、谓词和对象调用 Model.createStatement() ,还可以直接在模型上创建语句。注意以此种方式创建 Statement 不将其添加到模型中。如果想将其添加到模型中,请使用创建的 Statement 调用 Model.add() ,如清单 1 所示:
清单 1. 创建模型来表示虚构的家庭 构建了家庭模型后,我们看一下如何使用 Jena 的查询 API 从模型中提取信息。
查询 RDF 模型 程序化地查询 Jena 模型主要通过 list() 方法在 Model 和 Resource 接口中执行。可以使用这些方法获得满足特定条件的主题、对象和 Statement 。它们还返回 java.util.Iterator 的特殊化,其具有返回特定对象类型的其他方法。 我们返回 清单 1的家庭模型,看一下可以查询它的不同方法,如清单 2 所示:
清单 2. 查询家庭模型
清单 3. 使用选择器查询模型
导入和持久化模型 不是所有的应用程序都从空模型开始。更常见的是,在开始时从现有数据填充模型。在这种情况下,使用内存模型的缺点是每次启动应用程序时都要从头重新填充模型。另外,每次关闭应用程序时,对内存模型进行的更改都将丢失。 一种解决方案是使用 Model.write() 序列化模型到文件系统,然后在开始时使用 Model.read() 将其取消序列化。不过,Jena 还提供了持久化模型,它们会被持续而透明地持久存储到后备存储器。Jena 可以在文件系统中或在关系数据库中持久化它的模型。当前支持的数据库引擎是 PostgreSQL、Oracle 和 MySQL。 WordNet WordNet 是“英文语言的词汇数据库”。我使用的是 Sergey Melnik 和 Stefan Decker 的 RDF 表示。它具有四个单独的模型,本文示例中将使用其中三个模型。 WordNet-nouns 模型包含 WordNet 表示的所有“词汇概念”和用于表示每个概念的“单词形式”。例如,它包含由单词形式“domestic dog”、“dog”和“Canis familiaris”表示的词汇概念。 第二个模型是 WordNet-glossary。它提供模型中每个词汇概念的简短定义。“dog”的词汇概念具有词汇条目“a member of the genus Canis (probably descended from the common wolf) that has been domesticated by man since prehistoric times.” WordNet-hyponyms 是第三个模型。它定义模型中概念的层次结构。概念“dog”是概念“canine”下位词,而“canine” 本身是概念“carnivore”的下位词。
图 2. 合并的 WordNet nouns 和 glossary 模型的结构 创建数据库后台模型的第一步是说明 MySQL 驱动类,并创建 DBConnection 实例。 DBConnection 构造函数使用用户的 ID 和密码登录到数据库。它还使用包含 Jena 使用的 MySQL 数据库名称的数据库 URL 参数,格式为 "jdbc:mysql://localhost/dbname" 。Jena 可以在一个数据库内创建多个模型。 DBConnection 的最后一个参数是数据库类型,对于 MySQL,该参数为 "MySQL" 。 然后 DBConnection 实例可以与 Jena 的 ModelFactory 一起使用来创建数据库后台模型。 创建了模型后,可以从文件系统中读入 WordNet RDF 文档。不同的 Model.read() 方法可以从 Reader 、 InputStream 或 URL 填充模型。可以通过 Notation3 、N-Triples 或默认情况下通过 RDF/XML 语法解析模型。WordNet 作为 RDF/XML 进行序列化,所以不需要指定语法。读取模型时,可以提供基准 URI。基准 URI 用于将模型中的任何相对 URI 转换成绝对 URI。因为 WordNet 文档不包含任何相对 URI,所以此参数可以指定为 null 。 清单 4 显示了将 WordNet RDF/XML 文件导入到 MySQL 持久化模型的完整过程:
清单 4. 导入和持久化 WordNet 模型 仅使用 Jena 的 API 查询像 WordNet 这样巨大的模型将有一定的限制性,因为要执行的每类查询都将需要专门编写多行的代码。幸运的是,Jena 以 RDQL 形式提供了一种表达通用查询的机制。
RDF 数据查询语言(RDQL) RDQL 是 RDF 的查询语言。虽然 RDQL 还不是正是的标准,但已由 RDF 框架广泛执行。RDQL 允许简明地表达复杂的查询,查询引擎执行访问数据模型的繁重工作。RDQL 的语法表面上类似 SQL 的语法,它的一些概念对已经使用过关系数据库查询的人来说将比较熟悉。在 Jena Web 站点中可以找到极好的 RDQL 指南,但几个简单的示例会对说明基础知识大有帮助。 使用 jena.rdfquery 工具可以在命令行上对 Jena 模型执行 RDQL 查询。RDFQuery 从文本文件中获取 RDQL 查询,然后对指定的模型运行该查询。对数据库后台模型运行查询需要相当多的参数。清单 5 中显示了运行下列示例需要的完整命令行:
清单 5. 从命令行运行 RDQL 查询 清单 6 显示了您将检查的第一个查询:
清单 6. 查找“domestic dog”的 WordNet 词汇条目的 RDQL 查询
图 3. 清单 6 中的 WHERE 子句匹配的图形 运行查询的结果为: definition
清单 7. 查找“bear”的 WordNet 词汇条目的 RDQL 查询 definition
清单 8. 查找“panther”和“tiger”的 WordNet 上位词的 RDQL 查询
图 4. 清单 8 中 WHERE 子句匹配的图形 wordform 和 definition 都在 SELECT 子句中声明,所以它们都是输出。尽管词查询仅匹配了一个 WordNet 概念,查询的图形可以以两种方式匹配,因为该概念有两个不同的单词形式: wordform | definition
使用 Jena 中的 RDQL Jena 的 com.hp.hpl.jena.rdql 包包含在 Java 代码中使用 RDQL 所需的所有类和接口。要创建 RDQL 查询,将 RDQL 放入 String 中,并将其传送给 Query 的构造函数。通常直接设置模型用作查询的源,除非在 RDQL 中使用 FROM 子句指定了其他的源。一旦创建了 Query ,可以从它创建 QueryEngine ,然后执行查询。清单 9 中说明了此过程:
清单 9. 创建和运行 RDQL 查询
清单 10. 将查询变量与值绑定
清单 11. 查找“domestic dog”的 WordNet 词汇条目的 RDQL 查询 这种情况下, concept 变量表示 RDF 资源,所以从 ResultBinding.get() 获得的 Object 可以转换成 Resource 。然后可以调用 Resource 的查询方法来进一步探查这部分模型,如清单 12 中所示:
清单 12. 使用查询结果
清单 13. 查找概念的上位词的单词形式和词汇条目的 RDQL 查询
清单 14. 运行示例 FindHypernym 程序
使用 OWL 添加意义 您可能想知道为什么“wisteria”的上位词搜索仅返回它的直接上位词“vine”。如果从植物学观点,您可能还希望显示“traceophyte”也显示为上位词,以及“plant”。实际上,WordNet 模型表明“wisteria”是“vine”的下位词,“vine”是“traceophyte”的下位词。直观地,您知道“wisteria”因此是“traceophyte”的下位词,因为您知道“hyponym of”关系是 可传递的。所以您需要有一种方法将这种认识合并到 FindHypernym 程序中,从而产生了 OWL。 可传递关系 关系对于三个元素 a、 b和 c是可传递的,从而 a和 b之间及 b和 c之间存在关系意味着 a和 c之间存在关系。 可传递关系的一个示例是“大于”关系。如果 a大于 b, b大于 c,因而 a肯定大于 c。 在 Jena 中,本体被看作一种特殊类型的 RDF 模型 OntModel 。此接口允许程序化地对本地进行操作,使用便利方法创建类、属性限制等等。备选方法将本体看作特殊 RDF 模型,仅添加定义其语义规则的语句。清单 15 中说明了这些技术。注意还可以将本体语句添加到现有数据模型中,或使用 Model.union() 将本体模型与数据模型合并。
清单 15. 创建 WordNet 的 OWL 本体模型
使用 Jena 推理 给定了本体和模型后,Jena 的推理引擎可以派生模型未明确表达的其他语句。Jena 提供了多个 Reasoner 类型来使用不同类型的本体。因为要将 OWL 本体与 WordNet 模型一起使用,所以需要 OWLReasoner 。 下例显示了如何将 OWL WordNet 本体应用到 WordNet 模型自身以创建推理模型。这里我实际将使用 WordNet 模型的子集,仅包含下位词层次结构中“plant life”之下的那些名词。仅使用子集的原因是推理模型需要保存在内存中,WordNet 模型对于内存模型过大而不能实现。我用来从整个 WordNet 模型中提取 plants 模型的代码包含在文章来源中,名为 ExtractPlants.java(请参阅 参考资料)。 首先我从 ReasonerRegistry 中获得 OWLReasoner 。 ReasonerRegistry.getOWLReasoner() 在它的标准配置中返回 OWL reasoner,这对于此简单情况已经足够。下一步是将 reasoner 与 WordNet 本体绑定。此操作返回可以应用本体规则的 reasoner。然后,将使用绑定的 reasoner 从 WordNet 模型创建 InfModel 。 从原始数据和 OWL 本体创建了推理模型后,它就可以像任何其他 Model 实例一样进行处理。因此,如清单 16 所示,通过 FindHypernym.java 与正常 Jena 模型一起使用的 Java 代码和 RDQL 查询可以重新应用到推理模型,而不进行任何更改:
清单 16. 创建和查询推理模型
清单 17. 运行示例 FindInferredHypernyms 程序
结束语 本文说明了 Jena Semantic Web Toolkit 的一些最重要的功能,并用示例说明了如何创建、导入和持久化 RDF 模型。您已经了解了查询模型的不同方法,并看到了如何使用 RDQL 简明地表达任意查询。另外,您还了解了如何使用 Jena 的推理引擎对基于本体的模型进行推理。 本文中的示例已经说明了将数据表示为 RDF 模型的一些效果,以及 RDQL 从这些模型中提取数据的灵活性。当在您自己的 Java 应用程序中使用 RDF 模型时,这里说明的基本方法将是非常有用的起点。 Jena 是综合的 RDF 工具集,它的功能远不止您这里了解的这些。Jena 项目的主页是开始学习其功能的好地方。 |
-- 作者:ejun_2006 -- 发布时间:10/11/2007 9:26:00 PM -- 恩 是呀 不错多谢了!!! |
-- 作者:shaoguow -- 发布时间:10/12/2007 4:15:00 PM -- 赞一个 |
-- 作者:starrainlove -- 发布时间:10/13/2007 3:07:00 PM -- 非常感谢哈 |
-- 作者:todaysgp -- 发布时间:10/21/2007 11:48:00 PM -- 我记下了!谢谢,洗完以后都提供这样的宝贵资料! 谢谢了! |
-- 作者:xiemengjun -- 发布时间:10/22/2007 1:40:00 AM -- taihaole |
-- 作者:clandy -- 发布时间:10/23/2007 2:04:00 AM -- 好贴!学习ing |
-- 作者:30983638 -- 发布时间:11/24/2007 3:25:00 PM -- 翻译得不错 |
-- 作者:gazi945 -- 发布时间:11/25/2007 8:22:00 PM -- 实在是好东西 |
-- 作者:chairmanwei -- 发布时间:11/25/2007 9:13:00 PM -- 赞楼主一个先~ 不过这篇相对简单,不翻译无所谓,呵呵。 要是把推理的api翻译出来,那就好了,嘿嘿~~ 楼主不是对你的工作不敬啊~ |
-- 作者:supergg -- 发布时间:11/27/2007 10:24:00 AM -- 顶 |
-- 作者:delin -- 发布时间:12/20/2007 6:22:00 PM -- 赞一个!正在学习中! |
-- 作者:廋鹤一只 -- 发布时间:12/23/2007 10:02:00 PM -- thanks |
-- 作者:myldb_sw -- 发布时间:1/14/2008 9:10:00 PM -- 非常谢谢,正准备学习如何使用Jena |
-- 作者:guffey -- 发布时间:2/7/2008 9:08:00 PM -- 55楼,现在的jena版本好象改用sparql了,这几个例子怎么用sparql改写一下呢? |
-- 作者:guffey -- 发布时间:2/7/2008 10:34:00 PM -- import java.util.ArrayList; import java.util.List; import com.hp.hpl.jena.db.*; /** /** MySQL driver classname */ /** URL of database to use */ /** User credentials */ /** Name of the Jena model to create */ static public final String NL = System.getProperty("line.separator"); /** // ---- Execute expression // Check that the user provided a single argument try { // Get a connection to the db // Get hold of the existing wordnet model // results.close() ; 运行结果: Hypernyms found for 'tiger': -------------------------------------------------------------------------------------------- |
-- 作者:xiawared -- 发布时间:4/7/2008 3:33:00 PM -- 学习中。。。 |
-- 作者:dasotkb -- 发布时间:4/23/2008 2:36:00 PM -- thanks ...... good poster ~ |
-- 作者:hyue2009 -- 发布时间:4/27/2008 1:39:00 AM -- 谢谢! |
-- 作者:ganggao -- 发布时间:6/26/2008 12:16:00 PM -- 真的很好,非常感谢!!! |
-- 作者:jiangyue0011 -- 发布时间:7/1/2008 3:38:00 PM -- 支持外文资料的本土化进程!呵呵!楼主很强! |
-- 作者:mrcold -- 发布时间:7/26/2008 10:19:00 AM -- 不错 收藏了 |
-- 作者:lassiefly -- 发布时间:10/28/2008 4:01:00 PM -- 多谢! |
-- 作者:Humphrey -- 发布时间:10/29/2008 10:17:00 AM -- 姐姐果然不一般,感谢您为我们初学者提供易于接受的中文译文! |
-- 作者:hanfei813 -- 发布时间:2/23/2009 1:36:00 PM -- 非常感谢 |
-- 作者:lipeiqiang1997 -- 发布时间:3/10/2009 6:06:00 PM -- 你能不能把Jena API文档给我发一份。从网上下载不下来,我还是个新手,谢谢 |
-- 作者:lipeiqiang1997 -- 发布时间:3/10/2009 6:07:00 PM -- 我的邮箱是lipeiqiang84@163.com |
-- 作者:lipeiqiang1997 -- 发布时间:3/17/2009 4:29:00 PM -- 我想问一下Jena Tutorial的代码从哪里找啊,怎么我在HP的网站上找不到相关的资料那?哪位手里有的话可不可以给我发一份啊,或者上传到这个网站上,我的邮箱是 lipeiqiang84@163.com 谢谢了!!! |
-- 作者:lipeiqiang1997 -- 发布时间:3/17/2009 4:29:00 PM -- 我想问一下Jena Tutorial的代码从哪里找啊,怎么我在HP的网站上找不到相关的资料那?哪位手里有的话可不可以给我发一份啊,或者上传到这个网站上,我的邮箱是 lipeiqiang84@163.com 谢谢了!!! |
-- 作者:zym88 -- 发布时间:5/7/2009 11:04:00 AM -- 赞! 多谢!辛苦了! |
-- 作者:yinshiwei -- 发布时间:3/7/2011 5:41:00 PM -- 太感谢了 |
-- 作者:zhenzixiong -- 发布时间:3/22/2011 4:46:00 PM -- 崇拜得不行了 |
-- 作者:cpahuangyg -- 发布时间:9/26/2012 1:12:00 PM -- 感谢! |
-- 作者:廖娟娟 -- 发布时间:5/27/2015 9:07:00 PM -- 谢谢分享 |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
593.750ms |