语义 Web 为更轻松的数据集成开辟了一个新时代。当然,已经有很多现成的数据以各种不同的格式存在。要将所有这些数据转化成 RDF(语义 Web 使用的格式)将是一项庞大的工程,因此最好将已有的数据作为 RDF 公开。本文介绍了语义 Web 的核心概念和标准,阐述了如何将 LDAP 目录公开为语义 Web 应用程序可使用开放源码 SquirrelRDF 工具使用的服务。
本文的目的在于说明如何为 LDAP 目录创建可通过 SPARQL 查询的端点,同时介绍了重要的语义 Web 概念。建立端点之后,我还将说明如何使用一些 Jena Java? 类进一步完善,最后使用 JavaScript 从基于浏览器的客户端查询它,
语义 Web 是一种新出现的技术,它以表示数据、查询数据和对数据应用规则的一组标准为基础。核心技术包括用于表示的 RDF、用于查询的 SPARQL、用于构造的 RDFS 以及用于构造和推理的 OWL。语义 Web 有很多突出的优点,包括数据集成更简单、搜索更精确、知识管理更方便等等,结果语义 Web 这个词的含义越来越丰富。
RDF 和 XML 有一些重要的区别。首先,RDF 是基于图的,而 XML 是基于树的。RDF 没有明确的顺序,所有的边组成一个集合,而 XML 元素是有顺序的。最后,RDF 是一种不含标准序列化的数据模型。RDF 可以序列化成多种形式,包括 RDF-XML、n3、Terse RDF Triple Language等。清单 1 中的例子采用 Turtle 描述了关于两个人的一些联系信息。
@prefix foaf: .
a foaf:Person ;
foaf:name "Wing C. Yung" ;
foaf:mbox ;
foaf:phone "1-555-555-5555" ;
foaf:knows .
a foaf:Person ;
foaf:name "Lee Feigenbaum" ;
foaf:mbox ;
foaf:phone "1-555-555-5556" .
第一行定义了数据前缀,这样 DE>DE> 就能简写为 DE>foaf:nameDE>。可以指定多个前缀。此外,Turtle 用分号(DE>;DE>)表示后续行中的谓词和宾语使用相同的主语。谓词 DE>aDE> 是 RDF 类型谓词(DE>DE>)的缩写,可用于表示资源属于特定类型。
使用 SPARQL 查询 RDF
试验下面的查询可使用通用的 SPARQL 处理程序(请参阅 参考资料)。将 DE>http://wingerz.com/dw/listing1.ttlDE> 粘贴到 Target graph URI 字段中。输入查询并单击 Get Results 之后,就会检索 Turtle 文件并进行查询。
DE>SELECTDE>:返回满足查询的一组变量绑定(类似 SQL DE>SELECTDE>)。非常适合产生应用程序要消费的数据。
DE>CONSTRUCTDE>:返回一个图(一组 RDF 命题)。适合检索和转换 RDF。
DE>ASKDE>:返回一个布尔值,说明是否存在查询的结果。
DE>DESCRIBEDE>:依赖于实现。接收一个资源并返回描述该资源的图。
清单 2 示范了 DE>SELECTDE> 查询。
Query:
PREFIX foaf:
SELECT ?person ?phone
WHERE {
?person foaf:name "Wing C. Yung" .
?person foaf:phone ?phone
}
Result:
----------------------------------------------------
| person | phone |
====================================================
| | "1-555-555-5555" |
----------------------------------------------------
DE>CONSTRUCTDE> 非常重要,可以根据 SPARQL 查询结果构造 RDF 图。在数据合并的时候很方便,因为 CONSTRUCT 图中的谓词不一定和原图中的相同。清单中查询 DE>foaf:phoneDE>,不过在它的位置使用不同的谓词构造了一个新的图(DE>wingerz:officephoneDE>)。
Query:
PREFIX foaf:
PREFIX wingerz:
CONSTRUCT {
?person foaf:name "Wing C. Yung" .
?person wingerz:officephone ?phone
} WHERE {
?person foaf:name "Wing C. Yung" .
?person foaf:phone ?phone
}
Result:
1-555-555-5555Wing C. Yung
试验 DE>CONSTRUCTDE> 查询的时候,在资源页面上可以看到完整的响应。遗憾的是,结果被序列化为 RDF-XML 格式,不是很优雅的一种 RDF 序列化格式。
初看起来,RDF 数据似乎有点笨拙而且非常罗嗦。但是有一些突出的优点。
数据的结构没有限制。XML 是层次化的,在关系数据库中建模(和查询)图结构非常困难。
数据容易合并。合并数据(不同的图)是一项简单操作,只需要建立包含图中所有三元组的集合。全球唯一资源减少了歧义。而且如果必要的话,可以用 OWL 规则将不同 URI 的资源映射到同一个 URI。
SquirrelRDF 入门
LDAP 目录本身的结构很容易转化成 RDF。每个 LDAP 对象类都有一组属性。其中一些属性指向文字值(比如名称),另一些则指向其他对象[比如专用名词(DN)指定的工作地点]。
安装后,第一步是寻找 LDAP 存储的模式。如果没有可供试验的 LDAP 存储,可以安装 OpenLDAP 并按照使用说明创建一个简单的地址簿(请参阅 参考资料,尽管可能没有必要费这么多事,因为本文的目标是利用已有的数据源)。模式包含所有不同的对象类及其属性。通过分析属性,可以确定目录中对象之间的关系。
现在来创建从 LDAP 模式到 RDF 的映射。SquirrelRDF 使用 RDF 文件表示这种映射。DE>lmap:serverDE> 谓词用于指定 LDAP 存储的位置。映射允许分配两种类型的 RDF 谓词:文字宾语或者资源宾语。姓名和电话这类基本属性映射为文字宾语谓词。这类映射需要 LDAP 属性名和 RDF 谓词名。然后即可将其链接到资源。假设需要将 LDAP DE>cnDE> 映射到 RDF DE>foaf:nameDE>。清单 4 中创建了一个资源来进行链接 (DE>:namemappingDE>),然后将其链接到配置资源(DE>DE>)。
@prefix foaf: .
@prefix lmap: .
lmap:mapsProp :namemapping .
:namemapping lmap:property foaf:name
; lmap:attribute "cn" .
请注意,将这些链接到一起的 URI 无关紧要,可以改用空白节点,即没有 URI 的资源。它与空白 URI 的资源不同,后面也包括这样的资源。空白 URI 是一种相对 URI,因而解析到 Turtle 文件所在的位置。
清单 5. SquirrelRDF 文字映射到空白节点
@prefix foaf: .
@prefix lmap: .
lmap:mapsProp
[ lmap:property foaf:name
; lmap:attribute "cn" ]
要映射指向专有名词的 LDAP 属性,可将空白节点的类型指定为 DE>lmap:ObjectPropertyDE>。这样可以保证分配的谓词指向资源(而不是文字)。清单 6 显示了完整的配置文件,包括两个 DE>lmap:ObjectPropertyDE> 属性。LDAP 属性默认分配文字资源谓词。要注意,可能的话最好使用已有的谓词,这里使用了 FOAF 本体的一些词汇表。对于地点也有一个词汇表,不过这里没有用到。
@prefix rdf: .
@prefix foaf: .
@prefix lmap: .
@prefix people: .
@prefix ol: .
a lmap:Map ;
lmap:server ;
# Person properties
lmap:mapsProp
[ lmap:property foaf:name
; lmap:attribute "cn" ; ] ;
lmap:mapsProp
[ lmap:property foaf:phone
; lmap:attribute "telephoneNumber" ; ] ;
lmap:mapsProp
[ lmap:property people:ol
; lmap:attribute "officeLocation"
; a lmap:ObjectProperty ; ] ;
lmap:mapsProp
[ lmap:property people:manager
; lmap:attribute "manager"
; a lmap:ObjectProperty ; ] ;
# OfficeLocation properties
lmap:mapsProp
[ lmap:property ol:address1
; lmap:attribute "address1" ; ] ;
lmap:mapsProp
[ lmap:property ol:address2
; lmap:attribute "address2" ; ] ;
lmap:mapsProp
[ lmap:property ol:city
; lmap:attribute "city" ; ] ;
lmap:mapsProp
[ lmap:property ol:state
; lmap:attribute "state" ; ] ;
lmap:mapsProp
[ lmap:property ol:postalCode
; lmap:attribute "postalCode" ; ] ;
.
实验映射
清单 7. 测试查询 (test.rq)
PREFIX foaf:
SELECT ?person ?phone
WHERE {
?person foaf:name "Wing C Yung" .
?person foaf:phone ?phone
}
以 DE>dw.ttlDE>(映射文件名)和 DE>test.rqDE>(查询文件名)为参数运行 DE>squirrelrdf.QueryDE>。应该会得到某个人的 URI 和电话号码。
清单 8. 测试查询 (test2.rq)
PREFIX foaf:
SELECT ?person ?city ?name
WHERE{
?person foaf:name ?name .
?person people:ol ?officelocation .
?officelocation ol:state "MA" ;
ol:city ?city
}
将 SquirrelRDF 设置成服务
缺省 Servlet 非常小,只能回答 DE>SELECTDE> 查询,用标准 XML 格式表示结果集。为了使 SPARQL 端点更有用,可让它支持更多的特性。
增加更多的功能之前,我们先要找一种更好的办法测试端点,因为 URL 编码查询和手工创建 URL 都很麻烦。第一个例子使用的通用 SPARQL 处理程序无法再用,因为它取回执行查询的整个 RDF 图,我们的 SquirrelRDF 服务本身是一个能回答查询的 SPARQL 端点(通过将其转化成 LDAP 查询)。创建一个简单 HTML 表单编写和提交查询。一个例子是功能更完善的 SPARQLer(请参阅 参考资料)。单击 Graphs 选项卡来设置端点 endpoint(比如 http://localhost:8080/squirrel)。单击 Change。建立查询提交的端点。尝试本文前面用到的查询。
如前所述,DE>CONSTRUCTDE> 查询很重要,尤其是对非 RDF 格式存储的数据。现在,Servlet 仅支持 DE>SELECTDE> 查询,但是底层的查询引擎可以执行全部四种查询类型。扩展现有的 Servlet 需要修改 DE>doQuery()DE> 方法,如清单 9 所示。DE>com.hp.hpl.jena.query.QueryDE> 对象知道是什么类型的查询,因此可通过它确定 DE>com.hp.hpl.jena.query.engine1.QueryEngineDE> 应该怎么做。不同的查询类型返回不同类型的数据:DE>ASKDE> 返回布尔值,DE>CONSTRUCTDE> 和 DE>DESCRIBEDE> 返回图(从技术上说,返回的是图的包装 DE>ModelDE>),DE>SELECTDE> 返回结果集。
Query q = QueryFactory.create(theQuery, ".", Syntax.syntaxSPARQL);
int queryType = q.getQueryType();
Model m = null;
switch(queryType){
case Query.QueryTypeAsk:
boolean b = qe.execAsk();
String str = ResultSetFormatter.asXMLString(b);
resp.setHeader("Content-Type", "application/xml");
resp.getOutputStream().write(str.getBytes());
break;
case Query.QueryTypeConstruct:
// Gets a model.
m = qe.execConstruct();
resp.setHeader("Content-Type", "application/rdf+xml");
// A Model can serialize itself.
// The serialization format can be passed in as an argument,
// default is to write out as RDF/XML.
m.write(resp.getOutputStream());
break;
case Query.QueryTypeDescribe:
m = qe.execConstruct();
resp.setHeader("Content-Type", "application/rdf+xml");
m.write(resp.getOutputStream());
break;
case Query.QueryTypeSelect:
ResultSet results = qe.execSelect();
resp.setHeader("Content-Type", "application/xml");
ResultSetFormatter.outputAsXML(resp.getOutputStream(), results);
break;
}
获得 JSON 输出
清单 10. JSON 查询结果
{
"head": {
"vars": [ "person" , "phone" ]
} ,
"results": {
"distinct": false ,
"ordered": false ,
"bindings": [
{
"person": { "type": "uri" , "value": "http://wingerz.com/who#wing" } ,
"phone": { "type": "literal" , "value": "1-555-555-5555" }
}
]
}
}
DE>com.hp.hpl.jena.query.ResultSetFormatterDE> 工具类用于输出 SPARQL 查询结果。清单 9 使用它以 XML 格式输出结果(DE>SELECTDE> 和 DE>ASKDE> 查询)。结果也可以用 RDF 格式。毫不奇怪,使用这个工具类也能将 DE>SELECTDE> 结果邦定输出为 JSON,如清单 11 所示。
String output = req.getParameter("output");
if (output.equals("json")){
resp.setHeader("Content-Type", "application/json");
ResultSetFormatter.outputAsJSON(resp.getOutputStream(), results);
}
支持 XSLT
可以向服务器上增加 XSLT 服务,通过外部 XSLT 服务处理查询结果,或者在 XML 输出重增加样式表链接。在 XML 输出中添加样式表链接,将 DE>com.hp.hpl.jena.query.ResultSetFormatterDE> 作为 XSLT URI 的新增参数传递,如清单 13 所示。这样不会执行转换,只是在生成的文档中包括到 XSLT 的链接。当 XSLT 处理程序(比如现代 Web 浏览器)准备文档的时候就会执行转换了(请参阅 参考资料)。
http://wingerz.com/who#wing1-555-555-5555
清单 13. 包括 XSLT
引用
String stylesheet = req.getParameter("xslt");
if (stylesheet != null)
ResultSetFormatter.outputAsXML(resp.getOutputStream(), results, stylesheet);
else
ResultSetFormatter.outputAsXML(resp.getOutputStream(), results);
从 JavaScript 查询
中提供了可免费下载的 SPARQL JavaScript 库。主要用于处理 SPARQL DE>SELECTDE> 查询返回的 JSON 格式的结果。所幸的是,可以让 SPARQL 服务支持这种功能。该库背后最突出的思想是转换器的概念——SPARQL 端点的 JSON 输出包含一般客户机可能用不到的一些数据,比如某些数据类型信息。转换器将 JSON 输出转换成更容易使用的、更自然的对象。
分享到:
相关推荐
基于语义视图的SPARQL-SQL查询转换方法.pdf
该基准目前提供14个测试查询。该文件包含所有使用SPARQL 1.0语法的查询,并用空行分隔并标识注释。
通过对经典RDF模型添加时间戳表示其时间维度,并对时态RDF图中的蕴涵问题进行了讨论,根据SPARQL查询语言提出了完备的时态RDF查询语言T-SPARQL,并对提出的查询语言进行了可行性以及性能的实验仿真。利用该时态RDF...
中文!看了,你肯定能学会RDF数据查询语言SPARQL!
为了用户能够方便地获取本体知识,提出了基予自然语言理解的SPARQL本体查询。利用StanfordParser·分析用戸的自然语言查询,根据语法构建查询三元组,与关键词的方法相比,有效地减少了组合的个数。结舍 用户词典,...
SPARQL.js将SPARQL转换为JSON并返回,因此您可以在JavaScript应用程序中解析和构建SPARQL查询。 它还在sparqlStar选项下包含对扩展的sparqlStar 。 它完全支持,包括,和。 用法 图书馆 // Parse a SPARQL query ...
记录SPARQL查询sparql-doc支持用于记录sparql查询的标记,以及用于查询集合的程序包元数据。 这些功能将在下一节中介绍。SPARQL文档扩展sparql-doc处理您的SPARQL查询并查找注释。 与Javadoc,rdoc和类似工具一样,...
时态RDF扩展及其SPARQL查询语言
#资源达人分享计划#
重抽样方法是常用的解决数据非平衡问题的一种有效手段,为提高入侵检测系统的检测效率,降低数据的不平衡程度,提出了快速分层最近邻FHNN重抽样方法,采用两阶段的基于负载均衡策略的高速网络入侵检测模型,按协议...
neo4j-sparql-扩展 用于存储和功能的 Neo4j。 安装 从下载最新版本并将其放置在 Neo4j 服务器安装的/plugins/目录中。 要启用扩展,请将其添加到/conf/neo4j-server....SPARQL 协议(SPARQL 1.1 查询) 基础资源:
针对当前智能手机应用安全知识等信息的共享及复用问题,...利用本体查询语言SPARQL实现基于RDF三元组的各类相关查询;在此基础上,借助本体推理机制进行了推理研究,并结合实例,验证了研究内容的可行性和实用价值。
生成 SPARQL 查询并请求端点的库 例子 一个快速简单的 sparql 请求来了解它是如何工作的。 您可以在 SparqlTest.php 文件中找到更多示例。 $sparql = new Legrand\SPARQL; $sparql->variable('?z') ->where('...
LODQA(链接的开放数据问题解答)是使用自然语言查询来搜索SPARQL端点的系统,它从中生成SPARQL查询,将其提交给SPARQL端点,收集答案,并将其呈现给用户。 相依性 由于LODQA是Web界面服务,因此它通过与LODQA_BS...
OPCUA-SWT 该存储库提供了从OPC UA信息模型到RDF三元组和OWL本体的转换。 这种转换的目的是为OPC UA信息模型启用SPARQL查询支持。
文档详细介绍了RDF以及提供一种验证器, 利用Jena搭建了SPARQL对RDF数据进行查询等一些列操作。
ASQC提供了一个简单的命令行SPARQL查询客户端。 目的是可以将此客户端用于Unix风格的管道操作中,以执行查询操作序列,这些查询操作以RDF(来自CONSTRUCT查询)或变量绑定(来自SELECT查询)的形式传递信息。 安装 ...
SparQL(Simple Protocol and RDF Query Language),是为RDF开发的一种查询语言和数据获取协议,它是为W3C所开发的RDF数据模型所定义,但是可以用于任何可以用RDF来表示的信息资源。 SparQL 协议和 RDF 查询语言...
SPARQL本体查询语言教程.pdf
语义web里面主要的应用:查询,而查询需要的最重要的就是sparql查询语言,这个文档里面的主要内容就是sparql的语言规范