君子博学而日参省乎己 则知明而行无过矣

博客园 首页 新随笔 联系 订阅 管理

本文将对jena 的使用进行简单介绍。部分内容参考了这里 http://jena.apache.org/tutorials/rdf_api.html 。

 

1.  jena 包下载与开发环境配置

  • 首先,从这里下载 jena 包 apache-jana-2.7.*.tar.gz。解压。
  • 打开 Eclipse,新建一个Java Project。
  • 右键点击项目->properties->Java Build Path -> libraries。将解压后 lib 目录下的 jar 文件添加到build path 中。
  • OK。现在可以在项目里使用 jena 了。

2.  jena 简单使用

我们先看下面一个例子。这是一个 people 资源。RDF 中关于人的信息用vcard 来表示比较合适。关于 RDF 中 vCard 的更多内容参考http://www.w3.org/TR/vcard-rdf/

这个例子中,资源 http://.../JohnSmith 表示一个人。这个人的全名是 John Smith,即 vcard:FN 属性的值是 John Smith。在 Jena 中,资源用 Resource 类来表示,其属性用 Property 类来表示。而整体模型用Model 类来表示,即上图就是一个Model。一个 Model 对象可以包含多个资源。

上面所描述的资源使用 jena 编程表示如下:

  1. import com.hp.hpl.jena.rdf.model.Model;  
  2. import com.hp.hpl.jena.rdf.model.ModelFactory;  
  3. import com.hp.hpl.jena.rdf.model.Resource;  
  4. import com.hp.hpl.jena.vocabulary.VCARD;  
  5.   
  6. public class Introduction {  
  7.     static String personURI    = "http://somewhere/JohnSmith";  
  8.     static String fullName     = "John Smith";  
  9.   
  10.     public static void main(String[] args){  
  11.         // create an empty Model  
  12.         Model model = ModelFactory.createDefaultModel();  
  13.   
  14.         // create the resource  
  15.         Resource johnSmith = model.createResource(personURI);  
  16.   
  17.         // add the property  
  18.         johnSmith.addProperty(VCARD.FN, fullName);  
  19.     }  
  20. }  


其中, ModelFactory 类是一个Model 工厂,用于创建model 对象。我们可以使用 Model 的createResource 方法在model 中创建一个资源,并可以使用资源的 addProperty 方法添加属性。

 

3. jena 的 Statement

Model 的每个箭头都是一个陈述(Statement)。Statement 由三部分组成,分别是主语、谓语和客体。

  • 主语:图示中箭头出发的位置。代表资源。
  • 谓语:图示中的箭头。代表资源的属性。
  • 客体:图示中箭头指向的位置。代表属性的值。它可以是文本,也可以是一个资源。

下图表示一个Model:

它的每一个箭头都代表一个Statement。如资源http://.../JohnSmith 有一个vCard:FN 属性,其值是文本"John Smith ”。这个资源还有一个 vCard:N 属性,这个属性的值是另一个无名资源。该无名资源有两个属性,分别是 vCard:Given 和 vCard:Family。其值分别是文本的"John" 和 "Smith"。

我们可以用Jena API 来解析这个RDF 的Statement:

  1. import com.hp.hpl.jena.rdf.model.Model;  
  2. import com.hp.hpl.jena.rdf.model.ModelFactory;  
  3. import com.hp.hpl.jena.rdf.model.Property;  
  4. import com.hp.hpl.jena.rdf.model.RDFNode;  
  5. import com.hp.hpl.jena.rdf.model.Resource;  
  6. import com.hp.hpl.jena.rdf.model.Statement;  
  7. import com.hp.hpl.jena.rdf.model.StmtIterator;  
  8. import com.hp.hpl.jena.vocabulary.VCARD;  
  9.   
  10. public class StatementDemo {  
  11.     public static void main(String[] args){  
  12.           
  13.         //Introduction  
  14.         String personURI = "http://somewhere/JohnSmith";  
  15.         String givenName = "John";  
  16.         String familyName = "Smith";  
  17.         String fullName = givenName + " " + familyName;  
  18.         Model model = ModelFactory.createDefaultModel();  
  19.           
  20.         Resource johnSmith = model.createResource(personURI);  
  21.         johnSmith.addProperty(VCARD.FN, fullName);  
  22.         johnSmith.addProperty(VCARD.N,   
  23.                     model.createResource()  
  24.                         .addProperty(VCARD.Given, givenName)  
  25.                         .addProperty(VCARD.Family, familyName));  
  26.           
  27.         //Statement  
  28.         StmtIterator iter = model.listStatements();  
  29.           
  30.         while(iter.hasNext()){  
  31.             Statement stmt = iter.nextStatement();  
  32.             Resource subject = stmt.getSubject();  
  33.             Property predicate = stmt.getPredicate();  
  34.             RDFNode object = stmt.getObject();  
  35.               
  36.             System.out.print(subject.toString());  
  37.             System.out.print(" "+predicate.toString());  
  38.             if(object instanceof Resource){  
  39.                 System.out.print(object.toString());  
  40.             }else{  
  41.                 System.out.print("\"" + object.toString() + "\"");  
  42.             }  
  43.               
  44.             System.out.println(" .");  
  45.         }  
  46.     }  
  47. }  

Model 类的listStatements 将返回一个 Statement 的Iterator。Statement 有的主语、谓语、客体分别用 getSubject、getPredicate、getObject 来返回。其类型分别是 Resource、Property和RDFNode。其中客体 object 类型可以是Resource 或者文本。

该程序的输出如下:

  1. http://somewhere/JohnSmith http://www.w3.org/2001/vcard-rdf/3.0#N-1e19b4fe:13bd0803952:-7fff .  
  2. http://somewhere/JohnSmith http://www.w3.org/2001/vcard-rdf/3.0#FN"John Smith" .  
  3. -1e19b4fe:13bd0803952:-7fff http://www.w3.org/2001/vcard-rdf/3.0#Family"Smith" .  
  4. -1e19b4fe:13bd0803952:-7fff http://www.w3.org/2001/vcard-rdf/3.0#Given"John" .  

这四条分别代表了四个Statement,也即上面图中的四个箭头。
需要注意的是,这里有一个资源我们没有指定资源名。

4. 输出RDF

我们看下面的例子:

  1. import com.hp.hpl.jena.rdf.model.Model;  
  2. import com.hp.hpl.jena.rdf.model.ModelFactory;  
  3. import com.hp.hpl.jena.rdf.model.Resource;  
  4. import com.hp.hpl.jena.vocabulary.VCARD;  
  5.   
  6.   
  7. public class RDFWriting {  
  8.     public static void main(String[] args){  
  9.           
  10.         //Introduction  
  11.         String personURI = "http://somewhere/JohnSmith";  
  12.         String givenName = "John";  
  13.         String familyName = "Smith";  
  14.         String fullName = givenName + " " + familyName;  
  15.         Model model = ModelFactory.createDefaultModel();  
  16.           
  17.         Resource johnSmith = model.createResource(personURI);  
  18.         johnSmith.addProperty(VCARD.FN, fullName);  
  19.         johnSmith.addProperty(VCARD.N,   
  20.                     model.createResource()  
  21.                         .addProperty(VCARD.Given, givenName)  
  22.                         .addProperty(VCARD.Family, familyName));  
  23.           
  24.         //Model write  
  25.         model.write(System.out);  
  26.         System.out.println();  
  27.         model.write(System.out, "RDF/XML-ABBREV");  
  28.         System.out.println();  
  29.         model.write(System.out, "N-TRIPLE");  
  30.     }  
  31. }  

Model 同第三部分图示中所述一样。我们可以通过 Model 的write 方法将其model 中内容写入一个输出流。本例的输出为:

  1. <rdf:RDF  
  2.     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"  
  3.     xmlns:vcard="http://www.w3.org/2001/vcard-rdf/3.0#" >   
  4.   <rdf:Description rdf:about="http://somewhere/JohnSmith">  
  5.     <vcard:N rdf:nodeID="A0"/>  
  6.     <vcard:FN>John Smith</vcard:FN>  
  7.   </rdf:Description>  
  8.   <rdf:Description rdf:nodeID="A0">  
  9.     <vcard:Family>Smith</vcard:Family>  
  10.     <vcard:Given>John</vcard:Given>  
  11.   </rdf:Description>  
  12. </rdf:RDF>  
  13.   
  14. <rdf:RDF  
  15.     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"  
  16.     xmlns:vcard="http://www.w3.org/2001/vcard-rdf/3.0#">  
  17.   <rdf:Description rdf:about="http://somewhere/JohnSmith">  
  18.     <vcard:N rdf:parseType="Resource">  
  19.       <vcard:Family>Smith</vcard:Family>  
  20.       <vcard:Given>John</vcard:Given>  
  21.     </vcard:N>  
  22.     <vcard:FN>John Smith</vcard:FN>  
  23.   </rdf:Description>  
  24. </rdf:RDF>  
  25.   
  26. <http://somewhere/JohnSmith> <http://www.w3.org/2001/vcard-rdf/3.0#N> _:AX2dX498ae941X3aX13bd08e9fe5X3aXX2dX7fff .  
  27. <http://somewhere/JohnSmith> <http://www.w3.org/2001/vcard-rdf/3.0#FN> "John Smith" .  
  28. _:AX2dX498ae941X3aX13bd08e9fe5X3aXX2dX7fff <http://www.w3.org/2001/vcard-rdf/3.0#Family> "Smith" .  
  29. _:AX2dX498ae941X3aX13bd08e9fe5X3aXX2dX7fff <http://www.w3.org/2001/vcard-rdf/3.0#Given> "John" .  

可以看出,model.write(OutputStream),model.write(OutputStream, ”RDF/XML-ABBREV"),model.write(OutputStream, "N-TRIPLE") 分别输出了不同格式的内容。

  • model.write(OutputStream) : 也可以用model.write(OutputStream, null) 代替。默认的输出格式。
  • model.write(OutputStream, "RDF/XML-ABBREV"): 使用XML 缩略语法输出RDF。
  • model.write(OutputStream, "N-TRIPLE"): 输出n 元组的格式。

5. 输入RDF

我们有如下一个rdf 文件

resources.rdf:

  1. <rdf:RDF  
  2.   xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'  
  3.   xmlns:vcard='http://www.w3.org/2001/vcard-rdf/3.0#'  
  4.  >  
  5.   <rdf:Description rdf:nodeID="A0">  
  6.     <vcard:Family>Smith</vcard:Family>  
  7.     <vcard:Given>John</vcard:Given>  
  8.   </rdf:Description>  
  9.   <rdf:Description rdf:about='http://somewhere/JohnSmith/'>  
  10.     <vcard:FN>John Smith</vcard:FN>  
  11.     <vcard:N rdf:nodeID="A0"/>  
  12.   </rdf:Description>  
  13.   <rdf:Description rdf:about='http://somewhere/SarahJones/'>  
  14.     <vcard:FN>Sarah Jones</vcard:FN>  
  15.     <vcard:N rdf:nodeID="A1"/>  
  16.   </rdf:Description>  
  17.   <rdf:Description rdf:about='http://somewhere/MattJones/'>  
  18.     <vcard:FN>Matt Jones</vcard:FN>  
  19.     <vcard:N rdf:nodeID="A2"/>  
  20.   </rdf:Description>  
  21.   <rdf:Description rdf:nodeID="A3">  
  22.     <vcard:Family>Smith</vcard:Family>  
  23.     <vcard:Given>Rebecca</vcard:Given>  
  24.   </rdf:Description>  
  25.   <rdf:Description rdf:nodeID="A1">  
  26.     <vcard:Family>Jones</vcard:Family>  
  27.     <vcard:Given>Sarah</vcard:Given>  
  28.   </rdf:Description>  
  29.   <rdf:Description rdf:nodeID="A2">  
  30.     <vcard:Family>Jones</vcard:Family>  
  31.     <vcard:Given>Matthew</vcard:Given>  
  32.   </rdf:Description>  
  33.   <rdf:Description rdf:about='http://somewhere/RebeccaSmith/'>  
  34.     <vcard:FN>Becky Smith</vcard:FN>  
  35.     <vcard:N rdf:nodeID="A3"/>  
  36.   </rdf:Description>  
  37. </rdf:RDF>  


它包含有四个People 资源。下面的程序将读取该rdf 文件并再将内容输出:

  1. import java.io.InputStream;  
  2.   
  3. import com.hp.hpl.jena.rdf.model.Model;  
  4. import com.hp.hpl.jena.rdf.model.ModelFactory;  
  5. import com.hp.hpl.jena.util.FileManager;  
  6.   
  7. public class RDFReading {  
  8.     public static String inputFileName = "resources.rdf";  
  9.       
  10.     public static void main(String[] args){  
  11.         Model model = ModelFactory.createDefaultModel();  
  12.   
  13.         // 使用 FileManager 查找文件  
  14.         InputStream in = FileManager.get().open( inputFileName );  
  15.         if (in == null) {  
  16.             throw new IllegalArgumentException(  
  17.                                      "File: " + inputFileName + " not found");  
  18.         }  
  19.   
  20.         // 读取RDF/XML 文件  
  21.         model.read(in, null);  
  22.   
  23.         model.write(System.out);  
  24.     }  
  25. }  


Model 的read 方法可以读取RDF 输入到model 中。第二个参数可以指定格式。

6. 设置Namespace 前缀

我们看下面这个例子:

  1. import com.hp.hpl.jena.rdf.model.Model;  
  2. import com.hp.hpl.jena.rdf.model.ModelFactory;  
  3. import com.hp.hpl.jena.rdf.model.Property;  
  4. import com.hp.hpl.jena.rdf.model.Resource;  
  5.   
  6.   
  7. public class NSPrefix {  
  8.     public static void main(String[] args){  
  9.         Model m = ModelFactory.createDefaultModel();  
  10.         String nsA = "http://somewhere/else#";  
  11.         String nsB = "http://nowhere/else#";  
  12.           
  13.         //创建Resource 和 Property  
  14.         Resource root = m.createResource( nsA + "root" );  
  15.         Property P = m.createProperty( nsA + "P" );  
  16.         Property Q = m.createProperty( nsB + "Q" );  
  17.         Resource x = m.createResource( nsA + "x" );  
  18.         Resource y = m.createResource( nsA + "y" );  
  19.         Resource z = m.createResource( nsA + "z" );  
  20.           
  21.         //层叠增加三个Statement  
  22.         m.add( root, P, x ).add( root, P, y ).add( y, Q, z );  
  23.         System.out.println( "# -- no special prefixes defined" );  
  24.         m.write( System.out );  
  25.         System.out.println( "# -- nsA defined" );  
  26.           
  27.         //设置Namespace nsA 的前缀为“nsA”  
  28.         m.setNsPrefix( "nsA", nsA );  
  29.         m.write( System.out );  
  30.         System.out.println( "# -- nsA and cat defined" );  
  31.           
  32.         //设置Namespace nsB 的前缀为“cat”  
  33.         m.setNsPrefix( "cat", nsB );  
  34.         m.write( System.out );  
  35.     }  
  36. }  


该程序首先调用 Model 的createProperty 和createResource 生成属性和资源。然后调用Model.add 想model 中增加3个Statement。add 的三个参数分别是三元组的主语、谓语和客体。想Model 中增加内容实际上就是增加三元组。

Model 的 setNsPrefix 函数用于设置名字空间前缀。该程序的输出如下:

  1. # -- no special prefixes defined  
  2. <rdf:RDF  
  3.     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"  
  4.     xmlns:j.0="http://nowhere/else#"  
  5.     xmlns:j.1="http://somewhere/else#" >   
  6.   <rdf:Description rdf:about="http://somewhere/else#y">  
  7.     <j.0:Q rdf:resource="http://somewhere/else#z"/>  
  8.   </rdf:Description>  
  9.   <rdf:Description rdf:about="http://somewhere/else#root">  
  10.     <j.1:P rdf:resource="http://somewhere/else#y"/>  
  11.     <j.1:P rdf:resource="http://somewhere/else#x"/>  
  12.   </rdf:Description>  
  13. </rdf:RDF>  
  14. # -- nsA defined  
  15. <rdf:RDF  
  16.     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"  
  17.     xmlns:j.0="http://nowhere/else#"  
  18.     xmlns:nsA="http://somewhere/else#" >   
  19.   <rdf:Description rdf:about="http://somewhere/else#y">  
  20.     <j.0:Q rdf:resource="http://somewhere/else#z"/>  
  21.   </rdf:Description>  
  22.   <rdf:Description rdf:about="http://somewhere/else#root">  
  23.     <nsA:P rdf:resource="http://somewhere/else#y"/>  
  24.     <nsA:P rdf:resource="http://somewhere/else#x"/>  
  25.   </rdf:Description>  
  26. </rdf:RDF>  
  27. # -- nsA and cat defined  
  28. <rdf:RDF  
  29.     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"  
  30.     xmlns:cat="http://nowhere/else#"  
  31.     xmlns:nsA="http://somewhere/else#" >   
  32.   <rdf:Description rdf:about="http://somewhere/else#y">  
  33.     <cat:Q rdf:resource="http://somewhere/else#z"/>  
  34.   </rdf:Description>  
  35.   <rdf:Description rdf:about="http://somewhere/else#root">  
  36.     <nsA:P rdf:resource="http://somewhere/else#y"/>  
  37.     <nsA:P rdf:resource="http://somewhere/else#x"/>  
  38.   </rdf:Description>  
  39. </rdf:RDF>  

如果我们没有为RDF 指定namespace 前缀,则jena 会自动为其生成名为 j.0, j.1 的名字空间。

7. jena 的 Model 访问

上面介绍了jena 用来创建、读、写 RDF Model,本部分将主要用来访问RDF Model 的信息,对Model 的内容进行操作。

看下面一个例子:

  1. import com.hp.hpl.jena.rdf.model.Model;  
  2. import com.hp.hpl.jena.rdf.model.ModelFactory;  
  3. import com.hp.hpl.jena.rdf.model.Resource;  
  4. import com.hp.hpl.jena.rdf.model.StmtIterator;  
  5. import com.hp.hpl.jena.vocabulary.VCARD;  
  6.   
  7. public class ModelAccess {  
  8.     public static void main(String[] args){  
  9.         String personURI = "http://somewhere/JohnSmith";  
  10.         String givenName = "John";  
  11.         String familyName = "Smith";  
  12.         String fullName = givenName + " " + familyName;  
  13.         Model model = ModelFactory.createDefaultModel();  
  14.           
  15.         Resource johnSmith = model.createResource(personURI);  
  16.         johnSmith.addProperty(VCARD.FN, fullName);  
  17.         johnSmith.addProperty(VCARD.N,   
  18.                     model.createResource()  
  19.                         .addProperty(VCARD.Given, givenName)  
  20.                         .addProperty(VCARD.Family, familyName));  
  21.           
  22.         // 从 Model 获取资源  
  23.         Resource vcard = model.getResource(personURI);  
  24.           
  25.         /* 
  26.         // 获取N 属性的值(用属性的 getObject()方法) 
  27.         Resource name = (Resource) vcard.getProperty(VCARD.N) 
  28.                                         .getObject(); 
  29.         */  
  30.           
  31.         // 如果知道属性的值是资源,可以使用属性的getResource 方法  
  32.         Resource name = vcard.getProperty(VCARD.N)  
  33.                              .getResource();  
  34.           
  35.         // 属性的值若是 literal,则使用 getString 方法  
  36.         fullName = vcard.getProperty(VCARD.FN)  
  37.                                 .getString();  
  38.           
  39.         // 增加两个 NICKNAME 属性  
  40.         vcard.addProperty(VCARD.NICKNAME, "Smithy")  
  41.              .addProperty(VCARD.NICKNAME, "Adman");  
  42.           
  43.         System.out.println("The nicknames of \""  
  44.                               + fullName + "\" are:");  
  45.           
  46.         // 列出两个NICKNAME 属性,使用资源的 listProperties 方法  
  47.         StmtIterator iter = vcard.listProperties(VCARD.NICKNAME);  
  48.         while (iter.hasNext()) {  
  49.             System.out.println("    " + iter.nextStatement()  
  50.                                             .getObject()  
  51.                                             .toString());  
  52.         }  
  53.     }  
  54. }  

本例子中主要使用了以下内容

  • Model 的 getResource 方法:该方法根据参数返回一个资源对象。
  • Resource 的 getProperty 方法:根据参数返回一个属性对象。
  • Property 的 getObject 方法:返回属性值。使用时根据实际类型是 Resource 还是 literal 进行强制转换。
  • Property 的 getResource 方法:返回属性值的资源。如果属性值不是Resource,则报错。
  • Property 的 getString 方法:返回属性值的文本内容。如果属性值不是文本,则报错。
  • Resource 的 listProperties 方法:列出所找到符合条件的属性。

8. 对 Model 的查询

Jena 和核心 API 仅支持有限的查询操作。我们这里进行简单介绍。

  • Model.listStatements(): 列出Model 所有的Statements。
  • Model.listSubjects(): 列出所有具有属性的资源。
  • Model.listSubjectsWithProperty(Property p, RDFNode o): 列出所有具有属性p 且其值为 o 的资源。

上面所述的几种查询都是对 Model.listStatements(Selector s) 进行了一些包装得到的。如

  • Selector selector = new SimpleSelector(subject, predicate, object). 这个选择器选择所有主语符合 subject、谓语符合 predicate、客体符合 object 的Statement。

下面分别使用两种方式查询具有 fullName 的资源。

1. 使用 Model.listSubjectsWithProperty 查询:

  1. import java.io.InputStream;  
  2.   
  3. import com.hp.hpl.jena.rdf.model.Model;  
  4. import com.hp.hpl.jena.rdf.model.ModelFactory;  
  5. import com.hp.hpl.jena.rdf.model.ResIterator;  
  6. import com.hp.hpl.jena.util.FileManager;  
  7. import com.hp.hpl.jena.vocabulary.VCARD;  
  8.   
  9. public class RDFQuery {  
  10.     public static String inputFileName = "resources.rdf";  
  11.       
  12.     public static void main(String[] args){  
  13.         Model model = ModelFactory.createDefaultModel();  
  14.   
  15.         InputStream in = FileManager.get().open( inputFileName );  
  16.         if (in == null) {  
  17.             throw new IllegalArgumentException(  
  18.                                      "File: " + inputFileName + " not found");  
  19.         }  
  20.   
  21.         model.read(in, null);  
  22.   
  23.         //使用 listResourcesWithProperty  
  24.         ResIterator iter = model.listResourcesWithProperty(VCARD.FN);  
  25.         if(iter.hasNext()){  
  26.             System.out.println("The database contains vcard for:");  
  27.             while(iter.hasNext()){  
  28.                 System.out.println(" "+iter.nextResource().getProperty(VCARD.FN).getString());  
  29.             }  
  30.         }else{  
  31.             System.out.println("No vcards were found in the database");  
  32.         }  
  33.     }  
  34. }  

 

2. 使用 Selector 查询:

  1. import java.io.InputStream;  
  2.   
  3. import com.hp.hpl.jena.rdf.model.Model;  
  4. import com.hp.hpl.jena.rdf.model.ModelFactory;  
  5. import com.hp.hpl.jena.rdf.model.RDFNode;  
  6. import com.hp.hpl.jena.rdf.model.SimpleSelector;  
  7. import com.hp.hpl.jena.rdf.model.StmtIterator;  
  8. import com.hp.hpl.jena.util.FileManager;  
  9. import com.hp.hpl.jena.vocabulary.VCARD;  
  10.   
  11. public class RDFQuery1 {  
  12.     public static String inputFileName = "resources.rdf";  
  13.       
  14.     public static void main(String[] args){  
  15.         Model model = ModelFactory.createDefaultModel();  
  16.   
  17.         InputStream in = FileManager.get().open( inputFileName );  
  18.         if (in == null) {  
  19.             throw new IllegalArgumentException(  
  20.                                      "File: " + inputFileName + " not found");  
  21.         }  
  22.   
  23.         model.read(in, null);  
  24.   
  25.         //使用 Selector  
  26.         StmtIterator iter = model.listStatements(new SimpleSelector(null, VCARD.FN, (RDFNode)null));  
  27.         if(iter.hasNext()){  
  28.             System.out.println("The database contains vcard for:");  
  29.             while(iter.hasNext()){  
  30.                 System.out.println(" "+iter.nextStatement().getString());  
  31.             }  
  32.         }else{  
  33.             System.out.println("No vcards were found in the database");  
  34.         }  
  35.     }  
  36. }  

本例中使用resources.rdf 资源。上面两例的输出均为:

  1. The database contains vcard for:  
  2.  Becky Smith  
  3.  Matt Jones  
  4.  Sarah Jones  
  5.  John Smith  

9. 对Model 的增删操作

我们知道,对数据库的操作主要包括增、删、改、查等。对RDF 我们同样可以实现这几种操作。查询操作我们已经介绍过,本节将介绍RDF Model 的增删操作。我们可以对一个RDF 增加或者删除 Statement。由于 RDF Model完全是由 Statements 构成的,因此我们可以据此实现资源和属性等的增删。改动操作可以通过删除后再添加来实现。

看下面这个例子:

  1. import com.hp.hpl.jena.rdf.model.Model;  
  2. import com.hp.hpl.jena.rdf.model.ModelFactory;  
  3. import com.hp.hpl.jena.rdf.model.RDFNode;  
  4. import com.hp.hpl.jena.rdf.model.Resource;  
  5. import com.hp.hpl.jena.vocabulary.VCARD;  
  6.   
  7.   
  8. public class AddDelete {  
  9.     public static void main(String[] args){  
  10.         String personURI = "http://somewhere/JohnSmith";  
  11.         String givenName = "John";  
  12.         String familyName = "Smith";  
  13.         String fullName = givenName + " " + familyName;  
  14.         Model model = ModelFactory.createDefaultModel();  
  15.           
  16.         Resource johnSmith = model.createResource(personURI);  
  17.         johnSmith.addProperty(VCARD.FN, fullName);  
  18.         johnSmith.addProperty(VCARD.N,   
  19.                     model.createResource()  
  20.                         .addProperty(VCARD.Given, givenName)  
  21.                         .addProperty(VCARD.Family, familyName));  
  22.   
  23.         System.out.println("原始内容:");  
  24.         model.write(System.out);  
  25.         // 删除 Statement           
  26.         model.remove(model.listStatements(null, VCARD.N, (RDFNode)null));  
  27.         model.removeAll(null, VCARD.Given, (RDFNode)null);  
  28.         model.removeAll(null, VCARD.Family, (RDFNode)null);  
  29.           
  30.         System.out.println("\n删除后的内容:");  
  31.         model.write(System.out);  
  32.           
  33.         //增加 Statement  
  34.         model.add(johnSmith, VCARD.N, model.createResource()  
  35.                 .addProperty(VCARD.Given, givenName)  
  36.                 .addProperty(VCARD.Family, familyName));  
  37.         System.out.println("\n重新增加后的内容:");  
  38.         model.write(System.out);  
  39.     }  
  40. }  

在此例中,我们首先生成一个Model ,然后使用 Model.remove 方法删除几个statement 条目,然后使用Model.add 又增加了回来。

Model.remove 方法可以实现statement 的删除操作,Model.add 可以实现statement 的增加。

除了直接使用 Model 的方法外,对Model 中的Resource(资源)或Property(属性,实际上也继承自Resource)进行增删操作也可以达到更改 Model 的目的。

10 .Model 的合并操作

Model 的合并主要分为 交、并、补三种操作。

如下图所示:

          

这两个图分别代表一个Model。它们的名字相同,且具有相同的属性 vcard:FN ,值为John Smith。因此,我们对这两个Model 进行“并”(union)操作。所得到的Model 的图形表示如下:

其中重复的 vcard:FN 值只出现一个。

这三种操作的方法分别为:

  • Model.intersection(Model model): 交操作。创建一个新Model ,新Model 中包含之前两个Model 中都有的部分。
  • Model.union(Model model): 并操作。创建一个新Model,新 Model 中包含之前两个Model 中某一个具有的部分。
  • Model.difference(Model model): 补操作。创建一个新Model,新Model 中包含本Model 中有单在参数所示 Model 中没有的部分。

11. 总结

本文对核心 Jena API 进行了比较全面的介绍。Jena API 是处理RDF 的一个Java 框架。RDF 是用来进行资源描述的。

本文中的所有例子都经过本人调试运行正常。

需要了解 Jena 的更多内容,请参考 http://jena.apache.org/index.html 。

需要了解 RDF 的更多内容,请参考 http://www.w3.org/RDF/ 。另外http://www.w3school.com.cn/rdf/index.asp 是一个简明介绍。

posted on 2013-06-12 07:52  刺猬的温驯  阅读(712)  评论(0编辑  收藏  举报