知识图谱-Ontology应用建模实例:紧急联动的一个简单建模

2022-11-20  本文已影响0人  Viterbi

title: Ontology应用建模实例
tags: Ontology,知识图谱,小书匠 grammar_cjkRuby: true

[toc]

紧急联动的一个简单建模

UML模型(应急联动机构)

Ontology模型


<?xml version="1.0" encoding="GB2312"?>
<rdf:RDF 
    xmlns     ="http://gis.pku.edu.cn/应急联动机构#" 
    xmlns: 应急联动机构="http://www.example.org/应急联动机构#"      
    xmlns:owl ="http://www.w3.org/2002/07/owl#"
    xmlns:rdf ="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:xsd =http://www.w3.org/2000/10/XMLSchema#>
<owl:Ontology rdf:about=" http://gis.pku.edu.cn/应急联动机构"> 
  <rdfs:comment>中国城市应急联动机构的Ontology</rdfs:comment>
  <owl:versionInfo>
      $Id: test.html,v 1.0 2003/03/20 22:22:00 Lxp $
  </owl:versionInfo>
</owl:Ontology>
<owl:Class rdf:ID="&应急联动机构;联动单位"/ >
<owl:Class rdf:ID="&应急联动机构;消防局:">
    <rdfs:subClassOf rdf:resource="&应急联动机构;联动单位"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;联动单位调度中心"/ >
<owl:Class rdf:ID="&应急联动机构;处置力量分支"/ >
<owl:Class rdf:ID="&应急联动机构;消防指挥调度中心:">
    <rdfs:subClassOf rdf:resource="&应急联动机构;联动单位调度中心"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;消防支队:">
    <rdfs:subClassOf rdf:resource="&应急联动机构;处置力量分支"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;处置力量部门"/ >
<owl:Class rdf:ID="&应急联动机构;消防中队:">
    <rdfs:subClassOf rdf:resource="&应急联动机构; 处置力量部门"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;消防车"/ >
<owl:ObjectProperty rdf:ID="&应急联动机构;包含中心">   
  <rdf:type rdf:resource="&owl;FunctionalProperty" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含分支">   
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含联动调度中心">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含中心"/> 
	<rdfs:domain rdf:resource="&应急联动机构;联动单位" />
<rdfs:range rdf:resource="&应急联动机构;联动单位调度中心" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含力量分支">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含分支"/> 
	<rdfs:domain rdf:resource="&应急联动机构;联动单位" />
<rdfs:range rdf:resource="&应急联动机构;处置力量分支" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含力量部门">   
    <rdfs:subPropertyOf rdf:resource="&应急联动机构;包含分支"/> 
	<owl:allValuesFrom rdf:resource="&应急联动机构;处置力量部门"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含消防调度中心">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含中心"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防局" />
<rdfs:range rdf:resource="&应急联动机构;消防指挥调度中心" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含消防支队">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含分支"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防局" />
<rdfs:range rdf:resource="&应急联动机构;消防支队" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含中队">   
    <rdfs:subPropertyOf rdf:resource="&应急联动机构;包含分支"/> 
	<owl:allValuesFrom rdf:resource="&应急联动机构;消防中队"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含车">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含分支"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防中队" />
<rdfs:range rdf:resource="&应急联动机构;消防车" />
</owl:ObjectProperty>
</rdf:RDF>



一个比较复杂的应急联动的建模

UML模型

Ontology模型


<?xml version="1.0" encoding="GB2312"?>
<rdf:RDF 
    xmlns     ="http://gis.pku.edu.cn/应急联动机构#" 
    xmlns: 应急联动机构="http://www.example.org/应急联动机构#"      
    xmlns:owl ="http://www.w3.org/2002/07/owl#"
    xmlns:rdf ="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:xsd =http://www.w3.org/2000/10/XMLSchema#>
<owl:Ontology rdf:about=" http://gis.pku.edu.cn/应急联动机构"> 
  <rdfs:comment>中国城市应急联动机构的Ontology</rdfs:comment>
  <owl:versionInfo>
      $Id: test.html,v 1.1 2003/03/21 13:28:00 Lxp $
  </owl:versionInfo>
</owl:Ontology>
<owl:Class rdf:ID="&应急联动机构;联动单位"/ >
<owl:Class rdf:ID="&应急联动机构;消防局:">
    <rdfs:subClassOf rdf:resource="&应急联动机构;联动单位"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;联动单位调度中心"/ >
<owl:Class rdf:ID="&应急联动机构;处置力量分支"/ >
<owl:Class rdf:ID="&应急联动机构;处置力量编组"/ >
<owl:Class rdf:ID="&应急联动机构;消防指挥调度中心:">
    <rdfs:subClassOf rdf:resource="&应急联动机构;联动单位调度中心"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;消防支队:">
    <rdfs:subClassOf rdf:resource="&应急联动机构;处置力量分支"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;处置力量部门"/ >
<owl:Class rdf:ID="&应急联动机构;消防中队">
    <rdfs:subClassOf rdf:resource="&应急联动机构; 处置力量部门"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;消防车组">
    <rdfs:subClassOf rdf:resource="&应急联动机构; 处置力量编组"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;消防车"/ >
<owl:Class rdf:ID="&应急联动机构;联动单位调度员"/ >
<owl:Class rdf:ID="&应急联动机构;值班主任">
    <rdfs:subClassOf rdf:resource="&应急联动机构;联动单位调度员"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;处置部门调度员"/ >
<owl:Class rdf:ID="&应急联动机构;编组信息员"/ >
<owl:Class rdf:ID="&应急联动机构;调度单"/ >
<owl:Class rdf:ID="&应急联动机构;接警单"/ >
<owl:Class rdf:ID="&应急联动机构;消防调度单">
    <rdfs:subClassOf rdf:resource="&应急联动机构;调度单"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;通讯员">
    <rdfs:subClassOf rdf:resource="&应急联动机构; 编组信息员"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;电话员">
    <rdfs:subClassOf rdf:resource="&应急联动机构; 处置部门调度员"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;消防调度员"/ >
<owl:Class rdf:ID="&应急联动机构; 值班班长">
    <rdfs:subClassOf rdf:resource="&应急联动机构; 消防调度员"/>
</owl:Class>
<owl:Class rdf:ID="&应急联动机构;消防调度机"/ >
<owl:Class rdf:ID="&应急联动机构;调度机"/ >
<owl:Class rdf:ID="&应急联动机构;决策指挥中心"/ >
<owl:Class rdf:ID="&应急联动机构;决策指挥员"/ >
<owl:Class rdf:ID="&应急联动机构;决策指挥机"/ >
<owl:Class rdf:ID="&应急联动机构;应急联动中心"/ >
<owl:Class rdf:ID="&应急联动机构;综合调度员"/ >
<owl:Class rdf:ID="&应急联动机构;综合调度机"/ >
<owl:Class rdf:ID="&应急联动机构;接警员"/ >
<owl:Class rdf:ID="&应急联动机构;报警人"/ >
<owl:Class rdf:ID="&应急联动机构;接警机"/ >
<owl:Class rdf:ID="&应急联动机构;报警装置"/ >

<owl:ObjectProperty rdf:ID="&应急联动机构;包含中心">   
  <rdf:type rdf:resource="&owl;FunctionalProperty" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含分支">   
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含人员">   
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含调度员">   
	<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含人员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含设备">   
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含调度机">   
	<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含设备"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含联动调度中心">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含中心"/> 
	<rdfs:domain rdf:resource="&应急联动机构;联动单位" />
<rdfs:range rdf:resource="&应急联动机构;联动单位调度中心" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含力量分支">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含分支"/> 
	<rdfs:domain rdf:resource="&应急联动机构;联动单位" />
<rdfs:range rdf:resource="&应急联动机构;处置力量分支" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含力量部门">   
    <rdfs:subPropertyOf rdf:resource="&应急联动机构;包含分支"/> 
	<owl:allValuesFrom rdf:resource="&应急联动机构;处置力量部门"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含消防调度中心">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含中心"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防局" />
<rdfs:range rdf:resource="&应急联动机构;消防指挥调度中心" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含消防支队">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含分支"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防局" />
<rdfs:range rdf:resource="&应急联动机构;消防支队" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含中队">   
    <rdfs:subPropertyOf rdf:resource="&应急联动机构;包含分支"/> 
	<owl:allValuesFrom rdf:resource="&应急联动机构;消防中队"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含车组">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含分支"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防中队" />
<rdfs:range rdf:resource="&应急联动机构;消防车组" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含车">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含分支"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防车组" />
<rdfs:range rdf:resource="&应急联动机构;消防车" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含信息员">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含人员"/> 
	<rdfs:domain rdf:resource="&应急联动机构;处置力量编组" />
<rdfs:range rdf:resource="&应急联动机构;编组信息员" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含部门调度员">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含调度员"/> 
	<rdfs:domain rdf:resource="&应急联动机构;处治力量部门" />
<rdfs:range rdf:resource="&应急联动机构;处置部门调度员" />
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含主任">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含人员"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防车组" />
<rdfs:range rdf:resource="&应急联动机构;消防车" />
<owl:cardinality>1</owl:cardinality>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含综合调度员">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含调度员"/> 
	<rdfs:domain rdf:resource="&应急联动机构;应急联动中心"/>
<rdfs:range rdf:resource="&应急联动机构;综合调度员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含综合调度机">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含调度机"/> 
	<rdfs:domain rdf:resource="&应急联动机构;应急联动中心"/>
<rdfs:range rdf:resource="&应急联动机构;综合调度机"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含接警员">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含人员"/> 
	<rdfs:domain rdf:resource="&应急联动机构;应急联动中心"/>
<rdfs:range rdf:resource="&应急联动机构;接警员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含接警机">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含设备"/> 
	<rdfs:domain rdf:resource="&应急联动机构;应急联动中心"/>
<rdfs:range rdf:resource="&应急联动机构;接警机"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含指挥员">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含人员"/> 
	<rdfs:domain rdf:resource="&应急联动机构;抉择指挥中心"/>
<rdfs:range rdf:resource="&应急联动机构;决策指挥员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含指挥机">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含设备"/> 
	<rdfs:domain rdf:resource="&应急联动机构;抉择指挥中心"/>
<rdfs:range rdf:resource="&应急联动机构;决策指挥机"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含消防调度员">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含调度员"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防指挥调度中心"/>
<rdfs:range rdf:resource="&应急联动机构;消防调度员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含消防调度机">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含调度机"/> 
	<rdfs:domain rdf:resource="&应急联动机构; 消防指挥调度中心"/>
<rdfs:range rdf:resource="&应急联动机构; 消防调度机"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含班长">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含人员"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防指挥调度中心"/>
<rdfs:range rdf:resource="&应急联动机构;值班班长"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含电话员">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含人员"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防中队"/>
<rdfs:range rdf:resource="&应急联动机构;电话员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;包含通讯员">   
<rdfs:subPropertyOf rdf:resource="&应急联动机构;包含人员"/> 
	<rdfs:domain rdf:resource="&应急联动机构;消防车组"/>
<rdfs:range rdf:resource="&应急联动机构;通讯员"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="&应急联动机构;报警">
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;装置报警">
	<rdfs:subPropertyOf rdf:resource="&应急联动机构;报警"/>
	<rdfs:domain rdf:resource="&应急联动机构;报警装置"/>
<rdfs:range rdf:resource="&应急联动机构;接警员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;人员报警">
	<rdfs:subPropertyOf rdf:resource="&应急联动机构;报警"/>
	<rdfs:domain rdf:resource="&应急联动机构;报警人"/>
<rdfs:range rdf:resource="&应急联动机构;接警员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;设备报警">
	<rdfs:subPropertyOf rdf:resource="&应急联动机构;报警"/>
	<rdfs:domain rdf:resource="&应急联动机构;报警机"/>
<rdfs:range rdf:resource="&应急联动机构;接警员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;使用">
	<rdfs:domain rdf:resource="&应急联动机构;报警员"/>
<rdfs:range rdf:resource="&应急联动机构;消防调度员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;电话指令下达">
	<rdfs:domain rdf:resource="&应急联动机构;消防调度员"/>
<rdfs:range rdf:resource="&应急联动机构;电话员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;指挥通讯员">
	<rdfs:domain rdf:resource="&应急联动机构;消防调度员"/>
<rdfs:range rdf:resource="&应急联动机构;通讯员 "/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;调度现场情况汇报">
	<rdfs:domain rdf:resource="&应急联动机构;通讯员"/>
<rdfs:range rdf:resource="&应急联动机构; 消防调度员 "/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;填写调度情况">
	<rdfs:domain rdf:resource="&应急联动机构;消防调度员"/>
<rdfs:range rdf:resource="&应急联动机构;消防调度单"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;出动命令">
	<rdfs:domain rdf:resource="&应急联动机构;电话员"/>
<rdfs:range rdf:resource="&应急联动机构;通讯员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;指挥中队">
	<rdfs:domain rdf:resource="&应急联动机构;消防指挥调度中心"/>
<rdfs:range rdf:resource="&应急联动机构;消防车组"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;填写报警情况">
	<rdfs:domain rdf:resource="&应急联动机构;报警员"/>
<rdfs:range rdf:resource="&应急联动机构;报警单"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;指挥编组">
	<rdfs:domain rdf:resource="&应急联动机构;联动单位调度中心"/>
<rdfs:range rdf:resource="&应急联动机构;处置力量编组"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;处置指令下达">
	<rdfs:domain rdf:resource="&应急联动机构;联动单位调度员"/>
<rdfs:range rdf:resource="&应急联动机构;处置部门调度员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;出动命令">
	<rdfs:domain rdf:resource="&应急联动机构;联动单位调度员"/>
<rdfs:range rdf:resource="&应急联动机构;调度单"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;指挥信息员">
	<rdfs:domain rdf:resource="&应急联动机构;联动单位调度员"/>
<rdfs:range rdf:resource="&应急联动机构;编组信息员"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="&应急联动机构;编组现场情况汇报">
	<rdfs:domain rdf:resource="&应急联动机构;编组信息员"/>
<rdfs:range rdf:resource="&应急联动机构;联动单位调度员 "/>
</owl:ObjectProperty>
</rdf:RDF>



Jena——基于w3c的RDF、DAML/OIL进行语义网建模的Java API

简介——几个RDF建模的实例

给出下面的RDF有向图:


其中,椭圆中的URI给出了一个resource,有向边给出了该resource的一个property:FN(Full Name)。vcard是一个命名空间的前缀。该property的值在方框中给出,是一个literral类型的“John Smith”。 Jena一组能够用来创建和操纵诸如此种类型的有向图的Java API。Jena用对象类来表示图、resource、property和literal,用于表达后三者的接口分别叫做Resource、Property和Literal,而图被表示为一个model。用于创建上面的图的代码如下:


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

// create an empty graph
Model model = new ModelMem();

// create the resource 
Resource johnSmith = model.createResource(personURI);

// add the property
johnSmith.addProperty(VCARD.FN, fullName);


ModelMem是实现了接口Model的类。Jena还包括了其他用于实现Model的类,它们可以被存储在Berklay的DB数据库以及关系数据库中。VCARD是一个常数类,里面定义了所有VCARD Schema的常数。Jena还提供了其他常数类,如RDF、RDF Schema、Dublin Core 和DAML。其中,创建resource和添加property的两条语句可以被压缩为下面的一句:


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


下面给出了在例一的基础上得到的一个相对复杂的有向图: ![enter description here][4]

与上面不同的是,vcard:N属性以一个resource作为它的值,而该resource没有名字,称作一个空结点(blank Node)。 下面是Jena的创建代码:


// some definitions
String personURI    = "http://somewhere/JohnSmith";
String givenName    = "John";
String familyName   = "Smith";
String fullName     = givenName + " " + familyName;

// create an empty graph
Model model = new ModelMem();

// create the resource
//   and add the properties cascading style
Resource johnSmith 
  = model.createResource(personURI)
         .addProperty(VCARD.FN, fullName)
         .addProperty(VCARD.N, 
                      model.createResource()
                           .addProperty(VCARD.Given, givenName)
                           .addProperty(VCARD.Family, familyName));


Jena与整个建模流程

陈述(statement)

如上面的两个例子所示,RDF有向图中的每条边就是一个陈述,它肯定了resource的一个事实。一个陈述包含三个部分:

所以陈述又叫做三元组。 一个RDF有向图包含了一系列的陈述(statement),他是陈述的集合,所以重复的陈述可以被加进一个图中。Jena的model接口提供了一个listStatements()方法用于得到一个在这个集合上的迭代器,它的返回类型为Statement。Statement接口提供了用于访问该陈述的subject、predicate和object的方法。一个例子如下:


// list the statements in the graph
StmtIterator iter = model.listStatements();
            
// print out the predicate, subject and object of each statement
while (iter.hasNext()) {
    Statement stmt      = iter.next();         // get next statement
    Resource  subject   = stmt.getSubject();   // get the subject
    Property  predicate = stmt.getPredicate(); // get the predicate
    RDFNode   object    = stmt.getObject();    // get the object
                
    System.out.print(subject.toString());
    System.out.print(" " + predicate.toString() + " ");
    if (object instanceof Resource) {
       System.out.print(object.toString());
    } else {
        // object is a literal
        System.out.print(" \"" + object.toString() + "\");
    }
                
    System.out.println(" .");
} 


由于object可以为一个resource或者一个literal,所以getObject()方法返回一个类型为RDFNode的对象,该类是resource和literal的公共超类。

书写RDF

Jena提供了用XML格式读写RDF的方法,这就使得我们能够将一个RDF model存为一个文件并在以后将它读出来。
下面的代码片断给出了如何将一个model存入文件的方法:
// now write the model in XML form to a file
model.write(new PrintWriter(System.out));
即调用model的write方法通过一个PrintWriter写入文件中。 对于上面的例子,调用这样的输入语句可能得到下面的输出结果:


<rdf:RDF
  xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
  xmlns:vcard='http://www.w3.org/2001/vcard-rdf/3.0#'
 >
  <rdf:Description rdf:about='http://somewhere/JohnSmith'>
    <vcard:FN>John Smith</vcard:FN>
    <vcard:N rdf:resource='#A0'/>
  </rdf:Description>
  <rdf:Description rdf:about='#A0'>
    <vcard:Given>John</vcard:Given>
    <vcard:Family>Smith</vcard:Family>
  </rdf:Description>
</rdf:RDF>

不过该表达并不完全与我们上面给出的例子相符。在XML表达中不能描述一个空的节点,在原图中的空结点被赋予了一个URI。

Jena还提供了扩展接口用于支持可插入的新的writer来序列化RDF。上面使用的是标准的“dumb”writer,Jena还支持一个更为成熟的RDF/XML writer:


// now write the model in XML form to a file
model.write(new PrintWriter(System.out), "RDF/XML-ABBREV");

这个writer也叫做PrettyWriter,它能够使用RDF/XML feature的缩写语法更为紧凑的将一张图输出到文件。它同时也支持空结点。但是对于很大的图则不太适用,因为这样做的性能不能接收。要想输出很大的文件并且维持空结点,则使用N-Triples格式:

// now write the model in XML form to a file
model.write(new PrintWriter(System.out), "N-TRIPLE");

读取RDF

下面的代码给出了用于读取一个RDF文件并且将它另外写回的方法:


// create an empty model
 Model model = new ModelMem();
           
 // use the class loader to find the input file
 InputStream in = Tutorial05.class
                               .getClassLoader()
                               .getResourceAsStream(inputFileName);
if (in == null) {
    throw new IllegalArgumentException(
                                 "File: " + inputFileName + " not found");
}
            
// read the RDF/XML file
model.read(new InputStreamReader(in), "");
                        
// write it to standard out
model.write(new PrintWriter(System.out));

其中,read方法的第二个参数应该是相对的URI,因为这里没有引用相对URI,所以可以为空。

关于Jena的RDF包

在RDF有向图中的导航

给出一个resource的URL,可以使用Model.getResource(String uri)方法从图中得到该资源所对应的对象。如果对应的resource存在,则返回该resource的对象,否则将创建一个新的对象。例如:


// retrieve the John Smith vcard resource from the model
Resource vcard = model.getResource(johnSmithURI);

Resource接口定义了一系列方法用于访问一个Resource的Property。Resource.getProperty(Property p)方法用于访问一个resource的一个property。同以往的Java API不同的是该方法返回的是整个Statement对象,然后通过该对象的访问方法来得到Property的值。例如想得到vcard:N这个property的值所对应的resource,代码如下:


// retrieve the value of the N property
Resource name = (Resource) vcard.getProperty(VCARD.N)
                                .getObject();

由于property的值可能为resource或者literal,而我们已经知道上面得到的值为resource,所以进行了强制类型转换。Jena也提供了特定类型的访问方法,从而不需要在编译时进行类型转换。所以上面的代码也可以写成:


// retrieve the value of the FN property
Resource name = vcard.getProperty(VCARD.N)
.getResource();

类似,如果property的值为literal,则可以写成:


// retrieve the given name property
String fullName = vcard.getProperty(VCARD.FN)
                        .getString();
上面的property VCARD.FN只有一个,但RDF允许一个resource有重复的property。例如Adam可能有多于一个的nickname:

// add two nick name properties to vcard
vcard.addProperty(VCARD.NICKNAME, "Smithy")
     .addProperty(VCARD.NICKNAME, "Adman");

当调用getProperty方法时,Jena并没有定义要返回哪一个property,所以vcard.getProperty(VCARD.NICKNAME)的结果是不确定的。Jena只是返回其中任意一个,但并不保证连续两条调用都有可能返回同一个值。

这样,当proeprty连续出现时,可以使用Resource.listProperties(Property p)方法来得到一个迭代器从而列举出它们。例如下面的代码能够列举出上面添加的nickname:


	// set up the output
System.out.println("The nicknames of \""
                      + fullName + "\" are:");
// list the nicknames
StmtIterator iter = vcard.listProperties(VCARD.NICKNAME);
while (iter.hasNext()) {
    System.out.println("    " + iter.next()
                                    .getObject()
                                    .toString());
}

该代码的输出结果是:


The nicknames of "John Smith" are:
    Smithy
    Adman

关于图的查询

Jena核心只是提供了有限的查询元语。另外对RDF还有更为强大的RDQL查询语言。 Model.listStatements()方法用于列举一个model中的所有statement,可能是最为原始的对一个model的查询。该查询不适于在很大的图上面做查询。Model.listSubjects()方法类似,只是返回在所有有property的resource上的迭代器。Model.listSubjectsWithProperty(Property p, RDFNode o)则返回所有在property p上有值o的resource的迭代器。例如:


// retrieve all resource of type Vcard.
ResIterator iter = model.listSubjectsWithProperty(RDF.type, VCARD.Vcard);

如果我们使用的vcard schema并没有为vcard定义一个类型,那我们可以假定只有类型为vcard的resource有property vcard:FN,而且在我们的数据中,所有这样的resource都有一个这样的property,那我们可以这样进行查询:


// list vcards
ResIterator iter = model.listSubjectsWithProperty(VCARD.FN);
while (iter.hasNext()) {
    Resource r = iter.next();
    ...
}

所有上面的查询都基于这样一个查询元语:model.listStatements(Selector s)。该方法返回建立在经过s选择得到的statement上的迭代器。Selector被定义为可扩展的,目前只有一个实现:com.hp.hpl.mesa.rdf.jena.common包中的SelectorImpl类。SelectorImpl构造函数有三个参数:
Selector selector = new SelectorImpl(subject, predicate, object) 显然它返回匹配参数给出的三元组的statement。如果在这三个参数的位置上任意一个为null,则认为匹配所有。所以


Selector selector = new SelectorImpl(null, null, null);

返回一张图中的所有statement。


Selector selector = new SelectorImpl(null, VCARD.FN, null);

返回满足predicate为VCARD.FN的statement而不论其他两个参数的值为什么。以下的代码列出了数据库中所有vcard的full name:


// select all the resources with a VCARD.FN property
ResIterator iter = model.listSubjectsWithProperty(VCARD.FN);
if (iter.hasNext()) {
    System.out.println("The database contains vcards for:");
    while (iter.hasNext()) {
        System.out.println("  " + iter.next()
                                      .getProperty(VCARD.FN)
                                      .getString());
    }
} else {
    System.out.println("No vcards were found in the database");
}

输出结果可以是:


The database contains vcards for:
  Sarah Jones
  John Smith
  Matt Jones
  Becky Smith

下面的例子是采用SelectorImpl来实现查询的例子:


// select all the resources with a VCARD.FN property
// whose value ends with "Smith"
StmtIterator iter = model.listStatements(
  new 
      SelectorImpl(null, VCARD.FN, (RDFNode) null) {
          public boolean selects(Statement s) {
          try {
              return s.getString()
                      .endsWith("Smith");
          } catch (RDFException e) {
            throw new RDFError(e);
          }
     }
 });

以上的代码使用了Java的内置代理方法定义技术。其中select方法确保full name以“Smith”结束,而该过滤只是对subject起作用。
以下的两段代码可被认为是有着相同的功能: 【1】


// do all filtering in the selects method
StmtIterator iter = model.listStatements(
  new 
      SelectorImpl(null, null, (RDFNode) null) {
          public boolean selects(Statement s) {
          try {
              return (subject == null   || s.getSubject().equals(subject))
                  && (predicate == null || s.getPredicate().equals(predicate))
                  && (object == null    || s.getObject().equals(object))
          } catch (RDFException e) {
            throw new RDFError(e);
          }
     }
 });

【2】


	StmtIterator iter = 
  	model.listStatements(new SelectorImpl(subject, predicate, object)

前者列出图中所有的statement而后依次测试之,而后者允许使用应用实现本身维护的索引来提高性能。

对图的操作

Jena提供了3种针对图这一整体进行的操作——即典型的集合操作:并(union)、叫(intersection)和差(different)。 对两张图取并就是对两张图所包含的statement取并,这是为了支持RDF所给出的一个关键操作,它使得不同数据源的数据能够被合并。给出下面的两张图:

![enter description here][5]

它们可以被合并为:

上面的操作的代码是:


// read the RDF/XML files
model1.read(new InputStreamReader(in1), "");
model2.read(new InputStreamReader(in2), "");
            
// merge the graphs
Model model = model1.union(model2);
            
// print the graph as RDF/XML
model.write(new PrintWriter(System.out), "RDF/XML-ABBREV");
生成的RDF为:
<?xml version='1.0'?>
<rdf:RDF
    xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
    xmlns:RDFNsId1='http://www.w3.org/2001/vcard-rdf/3.0#'>
    <rdf:Description rdf:about='http://somewhere/JohnSmith/'>
        <RDFNsId1:N
             RDFNsId1:Given='John'
             RDFNsId1:Family='Smith'/>
        <RDFNsId1:FN>John Smith</RDFNsId1:FN>
        <RDFNsId1:EMAIL
             rdf:value='John@somewhere.com'
             rdf:type='http://www.w3.org/2001/vcard-rdf/3.0#internet'/>
    </rdf:Description>
</rdf:RDF>

交和差操作与此类似。

相关异常

目前Jena的异常机制不很受欢迎,它将在将来得到改进。由于Jena被设计成具有很高的灵活性并且支持不同的存储系统,所以存储管理器可以在任何时候给出一个非预期的错误。所以几乎所有的Jena方法在结尾都要注明要抛出RDFException异常。经验证明这不是一个好方法,当抛出异常时,通常这些异常都应该被忽略,检查出这些异常没有任何好处。

容器(Containers)

RDF给出了表达事物集合的特殊类型的resource。这些resource叫做容器。容器的成员或者是resource,或者是literal。共有3类容器:

下图是一个含有BAG的RDF有向图的示意:

注意BAG的成员标号rdf:_1和rdf:_2的顺序并不重要,它们可以被交换。而ALT的成员标号除了第一个是重要的(它是缺省的选择)外,也是顺序无关的。

Jena提供了明确的类接口和类实现用于表达容器,例如:


// create a bag
Bag smiths = model.createBag();
            
// select all the resources with a VCARD.FN property
// whose value ends with "Smith"
StmtIterator iter = model.listStatements(
    new SelectorImpl(null, VCARD.FN, (RDFNode) null) {
        public boolean selects(Statement s) {
            try {
                return s.getString()
                        .endsWith("Smith");
            } catch (RDFException e) {
                throw new RDFError(e);
            }
        }
    });
// add the Smith's to the bag
while (iter.hasNext()) {
    smiths.add(iter.next().getSubject());
}

由它得到的RDF为:


<rdf:RDF
  xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
  xmlns:vcard='http://www.w3.org/2001/vcard-rdf/3.0#'
 >
...
  <rdf:Description rdf:about='#A3'>
    <rdf:type rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag'/>
    <rdf:_1 rdf:resource='http://somewhere/JohnSmith/'/>
    <rdf:_2 rdf:resource='http://somewhere/RebeccaSmith/'/>
  </rdf:Description>
</rdf:RDF>

容器接口提供了一个迭代器用于列举它的成员:


// print out the members of the bag
NodeIterator iter2 = smiths.iterator();
if (iter2.hasNext()) {
    System.out.println("The bag contains:");
    while (iter2.hasNext()) {
        System.out.println("  " +
            (Resource) iter2.next())
                            .getProperty(VCARD.FN)
                            .getString());
    }
} else {
    System.out.println("The bag is empty");
}

上面的输出为:


The bag contains:
  John Smith
  Becky Smith

Jena类提供的用于操纵容器的方法包括:添加新成员、插入成员到容器的成员中部、删除成员等。

有关Literal和DataType的细节

RDF的literal不是简单的string。它可以包含一个语种标签来说明该literal的语种。语种标签为English的Literal“chat”和语种标签为“French”的Literal “chat”被认为是不同的literal。 进一步说,一共有两类literal:一种是普通的string,一种是一个定义良好的XML片断。例如下面的代码:


// create the resource
Resource r = model.createResource();                                     

// add the property
r.addProperty(RDFS.label, model.createLiteral("chat", "en"))
 .addProperty(RDFS.label, model.createLiteral("chat", "fr"))
 .addProperty(RDFS.label, model.createLiteral("<em>chat</em>", true));
          
// write out the graph
model.write(new PrintWriter(System.out));
它产生的RDF为:
<rdf:RDF
  xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
  xmlns:rdfs='http://www.w3.org/2000/01/rdf-schema#'
 >
  <rdf:Description rdf:about='#A0'>
    <rdfs:label xml:lang='en'>chat</rdfs:label>
    <rdfs:label xml:lang='fr'>chat</rdfs:label>
    <rdfs:label xml:lang='en' rdf:parseType='Literal'><em>chat</em></rdfs:label>
  </rdf:Description>
</rdf:RDF>

两个literal可以被看作相等的条件是:或者都是简单的literal,或者都是XML literal。而且要么都没有语种标签,要么有的话标签相同。

上一篇下一篇

猜你喜欢

热点阅读