Jena的一个例子

摘自:http://www.crabone.com/index.php/category/tool/jena

JENA中有一个最底层的接口:RDFNode,它代表RDF这张巨大图中的节点,这个节 点可以是一个资源,可以是一个字符窜或者数字。因此它对应与2个子接口:
interface Literal extends RDFNode
interface Resource extends RDFNode
Literal接口代表了一些原始类型节点,比如:32位整型、布尔型等等。
Resource接口还可以继续衍生出2个重要的接口:
interface Container extends Resource
interface Property extends Resource
Container接口就对应了RDF的容器表达能力,里面有bag,seq,alt
Property接口就是所谓的资源属性了

在RDF的世界中,其实描述资源只有一种方式,那就是三元组,包括:主体 (subject),谓词(predicate),客体(object)。主体和客体就是图中的2个节点,谓词就是一条边。这三元组在JENA中用 Statement接口来描述,该接口中有下面3个方法:
public Resource getSubject();
public Property getPredicate();
public RDFNode getObject();

我们可以发现,主体一定是一种资源,不可能是一个Literal原始类型,因此主体必定属于Resource接口实现,但是客体可以是原始类型,比如:人 有2条腿。 为主体; 为谓词;2 为客体。

用一个例子来巩固下:

  1. <? xml version = " 1.0 " ?>
  2. < rdf:RDF xmlns:rdf = " http://www.w3.org/1999/02/22-rdf-syntax-ns# "
  3. xmlns:s = " http://example.org/students/vocab# " >
  4. < rdf:Description rdf:about = " http://example.org/courses/6.001 " >
  5.    < s:students >
  6. < rdf:Bag >
  7.    < rdf:li rdf:resource = " http://example.org/students/Amy " />
  8.    < rdf:li rdf:resource = " http://example.org/students/Mohamed " />
  9.    < rdf:li rdf:resource = " http://example.org/students/Johann " />
  10.    < rdf:li rdf:resource = " http://example.org/students/Maria " />
  11.    < rdf:li rdf:resource = " http://example.org/students/Phuong " />
  12. </ rdf:Bag >
  13.    </ s:students >
  14. </ rdf:Description >
  15. </ rdf:RDF >

如果要一下子看出这个RDF中有几个三元组,一定不是很方便吧?如果用图来表示:
201001011021
是不是非常清晰呢?图中有一个主体http://example.org/courses/6.001,它有一条边http://example.org /students/vocab#students,对应的客体就是那个空节点。同理还有这个空节点所对应的那些三元组。用JENA来解析这个例子:

  1. Model model = ModelFactory . createDefaultModel () ;
  2. model . read ( new FileInputStream ( " student.rdf " ) , null ) ;
  3. StmtIterator it = model . listStatements () ;
  4. while ( it . hasNext ())
  5. {
  6. System . out . println ( it . next ()) ;
  7. }

打印的结果如下:
[http://example.org/courses/6.001, http://example.org/students/vocab#students, -23ba78ea:125e9da42c8:-8000]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#_5, http://example.org/students/Phuong]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#_4, http://example.org/students/Maria]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#_3, http://example.org/students/Johann]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#_2, http://example.org/students/Mohamed]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#_1, http://example.org/students/Amy]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag]

 

 

在RDF入门的例子中,有这样一幅图:
200912262132
最中间的那个节点起一个过渡作用,这时,虽然它也是一个资源,但这个资源没有必要标上资源描述符,因为它可能只在应用程序局部使用,作为推理机的一个桥梁 等等作用,换句说,这个资源别人没有必要去引用。这样的节点,我们称之为空节点:

  1. Model model = ModelFactory . createDefaultModel () ;
  2. Resource blankNode = model . createResource ( new AnonId ( " tempNode " )) ;
  3. Property city = model . createProperty ( " http://www.crabobe.com/city " ) ;
  4. Property street = model . createProperty ( " http://www.crabobe.com/street " ) ;
  5. blankNode . addProperty ( city , " 深圳 " ) ;
  6. blankNode . addProperty ( street , " 龙岗 " ) ;
  7. Resource crab = model . createResource ( " http://www.crabobe.com/crab " ) ;
  8. Property address = model . createProperty ( " http://www.crabobe.com/address " ) ;
  9. crab . addProperty ( address , blankNode ) ;
  10. model . write ( System . out ) ;

注意,包含中文的源码文件必须是UTF-8的,运行结果如下:

  1. < rdf:RDF
  2. xmlns:rdf = " http://www.w3.org/1999/02/22-rdf-syntax-ns# "
  3. xmlns:j . 0 = " http://www.crabobe.com/ " >
  4. < rdf:Description rdf:about = " http://www.crabobe.com/crab " >
  5. < j . 0:address rdf:nodeID = " A0 " />
  6. </ rdf:Description >
  7. < rdf:Description rdf:nodeID = " A0 " >
  8. < j . 0:street > 龙岗 </ j . 0:street >
  9. < j . 0:city > 深圳 </ j . 0:city >
  10. </ rdf:Description >
  11. </ rdf:RDF >

RDF作为资源描述框架,有2件事情是它的本职工作,第一,描述资源的唯一性,只有统一了,各种应用才能达成共识,好 比秦始皇那会儿一样。第二,要把资源表述得有条有理。下面,拿出代码来解释。

  1. Model model = ModelFactory . createDefaultModel () ;
  2. Resource crab = model . createResource ( " http://www.crabobe.com/crab " ) ;
  3. model . write ( System . out ) ;

上面,我们用jena建立了crab这样一个资源,当然,crab只是java内存中的一 个变量名而已,它真是的标识符号是http://www.crabobe.com/crab ,也即,在这个世界上,这 个资源是唯一存在的。

我们继续添加一个资源

  1. Model model = ModelFactory . createDefaultModel () ;
  2. Resource crab = model . createResource ( " http://www.crabobe.com/crab " ) ;
  3. Property numerOfLeg = model . createProperty ( " http://www.crabobe.com/crab#numerOfLeg " ) ;
  4. model . write ( System . out ) ;

这里我们添加了一个资源numerOfLeg,有人问,它是一个属性(Property)吧?没错,但在RDF中,属性也是一种资源,在JENA 中,Property是Resource的子接口。既然它是一种资源,那必定得有唯一的标识符,这个标识符就是http://www.crabobe.com/crab#numerOfLeg

接着我们用numerOfLeg这个属性来描述crab

  1. Model model = ModelFactory . createDefaultModel () ;
  2. Resource crab = model . createResource ( " http://www.crabobe.com/crab " ) ;
  3. Property numerOfLeg = model . createProperty ( " http://www.crabobe.com/crab#numerOfLeg " ) ;
  4. crab . addProperty ( numerOfLeg , " 8 " ) ;
  5. model . write ( System . out ) ;

运行的结果:

  1. < rdf:RDF
  2. xmlns:j . 0 = " http://www.crabobe.com/crab# "
  3. xmlns:rdf = " http://www.w3.org/1999/02/22-rdf-syntax-ns# " >
  4. < rdf:Description rdf:about = " http://www.crabobe.com/crab " >
  5. < j . 0:numerOfLeg > 8 </ j . 0:numerOfLeg >
  6. </ rdf:Description >
  7. </ rdf:RDF >

关于这个结果,虽然很简单,但是里面有个细节需要我们去关注!!同样是资源描述符,资源的 描述符和属性的描述符是不一样的。区别就体现在,资源的描述符仅仅是作为rdf:Description标签的一个属性 , 而属性的描述符却要被用来作为XML标签 。在这点上来看,属性的资源描述符一定要带有相对路径,假如我们这样写:
model.createProperty(”http://www.crabobe.com”);
那么这个属性标签的命名空间就没有了,如果命名空间标示为http://www.crabobe.com,那它自己的名称呢?所以,jena会报错。
所以,我们的写法可以是这样:
http://www.crabobe.com/crab
那么http://www.crabobe.com/就是命名空间,crab就是标签名称
也可以像例子都那样写:
http://www.crabobe.com/crab#numerOfLeg
那么命名空间就是http://www.crabobe.com/crab#,被jena简写成j.0,名称就是numerOfLeg。

现在,我们来验证资源的唯一性:

  1. Model model = ModelFactory . createDefaultModel () ;
  2. Resource crab = model . createResource ( " http://www.crabobe.com " ) ;
  3. Resource crab1 = model . createResource ( " http://www.crabobe.com " ) ;
  4. Property numerOfLeg = model . createProperty ( " http://www.crabobe.com/crab#numerOfLeg " ) ;
  5. Property numerOfLeg1 = model . createProperty ( " http://www.crabobe.com/crab#numerOfLeg " ) ;
  6. crab . addProperty ( numerOfLeg , " 8 " ) ;
  7. crab1 . addProperty ( numerOfLeg1 , " 8 " ) ;
  8. model . write ( System . out ) ;

这里,我们人为写出2个对象,但是资源描述符写成一样,这2个对象分别有各自属性,按照唯 一性,那么内存中即使对象再是多,在RDF规范中,只会认资源描述符,只要资源描述符是一样的,那么就视为一个资源。运行的结果,符合我们的推理。

如果我们改一改:

  1. Model model = ModelFactory . createDefaultModel () ;
  2. Resource crab = model . createResource ( " http://www.crabobe.com " ) ;
  3. Resource crab1 = model . createResource ( " http://www.crabobe.com " ) ;
  4. Property numerOfLeg = model . createProperty ( " http://www.crabobe.com/crab#numerOfLeg " ) ;
  5. Property numerOfLeg1 = model . createProperty ( " http://www.crabobe.com/crab#numerOfLeg " ) ;
  6. crab . addProperty ( numerOfLeg , " 8 " ) ;
  7. crab1 . addProperty ( numerOfLeg1 , " 10 " ) ;
  8. model . write ( System . out ) ;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值