Jena 官方 RDF API教程
依据官方教程改编而来
RDF(Resource Description Framework)是一套描述资源的标准

  • 每个资源(Resource)都拥有属性(Property)
  • 一般情况下资源会用统一资源标识符(URI)标识

基础

开始

假设首先声明了如下一个URI与fullName变量

static String personURI    = "http://somewhere/JohnSmith";
static String fullName     = "John Smith";

创建一个默认模型(Model)
Model model = ModelFactory.createDefaultModel();

创建一个资源
Resource johnSmith = model.createResource(personURI);
将属性添加到资源上
johnSmith.addProperty(VCARD.FN, fullName);

也可以使用级联方式定义

Resource johnSmith =
      model.createResource(personURI)
           .addProperty(VCARD.FN, fullName);

当前情况
1.png

进阶

向该模型中添加更多细节
添加约翰史密斯的givenName与familyName到模型中

String givenName    = "John";
String familyName   = "Smith";

可通过创建一个属性连接到一个空资源上,再创建额外两个属性连接到所提供的两个名称上,这两个名称便是Literal类型

johnSmith.addProperty(VCARD.N,
                      model.createResource()
                           .addProperty(VCARD.Given, givenName)
                           .addProperty(VCARD.Family, familyName));

如下图所示
fig2.png
图中vcard:N所指资源并没有URI,通常称为空节点(blank Node)

Statements

RDF模型中的每个arc(不知道咋翻译,圆弧?)称为statement
每个statement断言(asserts)了一个资源的事实(fact)
一个statement包含三个部分

the subject is the resource from which the arc leaves
the predicate is the property that labels the arc
the object is the resource or literal pointed to by the arc

statement有时也称作元组(triple),因为它的三元结构
一个RDF模型可以视为一组statement的集合
可通过listStatements()定义一个StmtIterator迭代器来访问statement
用法如下

StmtIterator iter = model.listStatements();
while (iter.hasNext()) {
    Statement stmt      = iter.nextStatement();  // get next statement
    Resource  subject   = stmt.getSubject();     // get the subject
    Property  predicate = stmt.getPredicate();   // get the predicate
    RDFNode   object    = stmt.getObject();      // get the object
}

通过上述方法可以遍历模型中的所有statement从而进一步处理数据
一个statement的object既可以是Resource类型也可以是Literal类型
可使用instanceof来判断object是否为Resource类型

 if (object instanceof Resource) {
       //object是Resource类型
    } 

internal identifier

很多时候在处理中会遇到诸如下列输出statement

[http://www.semanticweb.org/ontologies/2012/10/logistics.owl#订单, http://www.w3.org/2002/07/owl#equivalentClass, 6c51563f-8426-4970-a26a-21f70f4066b8]

其中出现不明标识符6c51563f-8426-4970-a26a-21f70f4066b8
官方文档解释说这是Jena产生的内部标识符(internal identifier),与URI不同,只是Jena内部使用的标签

撰写RDF

1.在控制台输出RDF

调用model的write()函数
model.write(System.out);
输出部分效果(自己提供的数据,编码错乱,手动加密(滑稽))
21.jpg

注意
RDF/XML不能表示所有RDF模型,比如说不能表示一个空白节点
默认不带参数的write函数调用的是"哑"编译器
实际上Jena还提供了更复杂的RDF/XML编写器
model.write(System.out, "RDF/XML-ABBREV");
然而该种编译器并不适合输出大文件,大文件最好的输出格式还是N-triples
model.write(System.out, "N-TRIPLES");

2.输出到文件

官方文档并没有详细阐述如何输出到文件,只说可以通过OutputStream进行文件输出
实际上操作也很简单
只要定义一个输出流

File file=new File(locate);
		OutputStream OutputTest = null;
		try {
			OutputTest =new FileOutputStream(file);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

随后调用RDFDataMgr中的write函数即可
包含三个参数
RDFDataMgr.write(OutputTest, model,lang) ;

  • OutputTest就是定义的输出流对象
  • model就是要输出的模型
  • lang就是要输出的语言

读取RDF

如何从文件中读取RDF?
通过建立一个输入流InputStream来从文件中读取数据
输入流可通过Jena提供的FileManger来建立

InputStream in = FileManager.get().open( inputFileName );
if (in == null) {
    throw new IllegalArgumentException(
                                 "File: " + inputFileName + " not found");

inputFileName为文件的路径
随后调用模型的read函数
model.read(in, null);

对数据进行处理

1.简单查询

Model.listSubjectsWithProperty(Property p, RDFNode o)
该函数返回一个ResInterator迭代器,里面包含属性为p,宾语为o的资源
详细用法

ResIterator iter = model.listSubjectsWithProperty(VCARD.FN);
while (iter.hasNext()) {
    Resource r = iter.nextResource();

测试(查找数据集中具有domain属性的资源)
1.jpg

ResourceOutput
________________________________________________________
http://www.semanticweb.org/ontologies/2012/10/logistics.owl#下订单
http://www.semanticweb.org/ontologies/2012/10/logistics.owl#订货数量
http://www.semanticweb.org/ontologies/2012/10/logistics.owl#发货
http://www.semanticweb.org/ontologies/2012/10/logistics.owl#订货日期
http://www.semanticweb.org/ontologies/2012/10/logistics.owl#发货日期
http://www.semanticweb.org/ontologies/2012/10/logistics.owl#订货人
________________________________________________________

2.专用选择器Selecter

Selector selector = new SimpleSelector(subject, predicate, object);
在SimpleSelector中输入对应的约束
比如说查找谓语为VCARD.N的语句
Selector selector = new SimpleSelector(null, VCARD.FN, null);

实际上

listStatements(S,P,O)
与下列语句是等同的
listStatements(new SimpleSelector(S,P,O))

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议