Javascript实现关联数据(Linked Data)查询及注意细节


Posted in Javascript onFebruary 22, 2013

前言
自由百科全书不仅仅应当可以自由编写,而更应该可以自由获得。
DBpedia对Wikipedia的数据变成Linked Data形式,使得机器也能读懂并自由获得这些数据。
本文的主要目的是利用Javascript从DBpedia中获取我们想要的数据。
对Linked Data不太了解的请参考:关联数据入门——RDF。

SPARQL
Trying to use the Semantic Web without SPARQL is like trying to use a relational database without SQL.
—— Tim Berners-Lee
SPARQL是Semantic Web(语义网)的SQL,用于数据查询的语言。

SPARQL Endpoint
SPARQL查询终端,是一种HTTP绑定协议,用于通过HTTP进行SPARQL查询,并返回相应数据。
DBpedia的SPARQL Endpoint地址是:http://dbpedia.org/sparql
大家可以通过浏览器打开这个页面,进行SPARQL查询(最好翻墙,没翻墙查询经常失败,不太明白为什么= =)。
不过这种查询最终返回结果是HTML页面,并不是我们想要的,我们可以通过设置Request Header的Accept属性来指定返回数据类型。
例如如果指定为:text/xml,那么返回的便是RDF格式数据。
那么我们如何输入SPARQL查询代码呢?
只需通过get或者post方法用参数query,将代码传过去。例如:
如果想查询:select distinct ?Concept where {[] a ?Concept} LIMIT 100
则可利用该链接得到数据:
http://dbpedia.org/sparql?query=select%20distinct%20?Concept%20where%20{[]%20a%20?Concept}%20LIMIT%20100
其中空格被转成%20。

实现细节
•跨域
我们可以通过AJAX实现这一功能,但是AJAX在部分浏览器中无法跨域,然而很显然我们想要的Linked Data几乎都是跨域的。
实际上,在一些较老版本的浏览器,我们没有不改变其数据形式的方法在前端进行动态跨域异步读取。
不过我们可以通过服务器代理的方法来解决跨域问题。
•GET or POST
使用GET还POST呢?
这个可能出于很多方面考虑,但是考虑到GET可能被缓存,所以我们使用POST来避免数据被缓存。
•以什么形式返回数据
前面我们说到用text/xml可以返回RDF数据,但是RDF在Javascript中并不好处理,所以我们使用json方式返回,也就是需要将Accept设置成application/sparql-results+json。

实现
接口参考Python的SPARQL Wrapper

(function(root, factory) { 
if(typeof define === "function"){ 
define("SPARQLWrapper", factory); // AMD || CMD 
}else{ 
root.SPARQLWrapper = factory(); // <script> 
} 
}(this, function(){ 
'use strict' 
function SPARQLWrapper(endpoint){ 
this.endpoint = endpoint; 
this.queryPart = ""; 
this.type = "json"; 
} 
SPARQLWrapper.prototype = { 
constructor: SPARQLWrapper, 
setQuery: function(query){ 
this.queryPart = "query=" + encodeURI(query); 
}, 
setType: function(type){ 
this.type = type.toLowerCase(); 
}, 
query: function(type, callback){ 
callback = callback === undefined ? type : this.setType(type) || callback; 
var xhr = new XMLHttpRequest(); 
xhr.open('POST', this.endpoint, true); 
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); 
switch(this.type){ 
case "json": 
type = "application/sparql-results+json"; 
break; 
case "xml": 
type = "text/xml"; 
break; 
case "html": 
type = "text/html"; 
break; 
default: 
type = "application/sparql-results+json"; 
break; 
} 
xhr.setRequestHeader("Accept", type); 
xhr.onreadystatechange = function(){ 
if(xhr.readyState == 4){ 
var sta = xhr.status; 
if(sta == 200 || sta == 304){ 
callback(xhr.responseText); 
}else{ 
console && console.error("Sparql query error: " + xhr.status + " " + xhr.responseText); 
} 
window.setTimeout(function(){ 
xhr.onreadystatechange= new Function(); 
xhr = null; 
},0); 
} 
} 
xhr.send(this.queryPart); 
} 
} 
return SPARQLWrapper; 
}));

使用方法,例如需要查询:
select distinct ?Concept where {[] a ?Concept} LIMIT 100
则该页面为:
<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
<script src="SPARQLWrapper.js" type="text/javascript"></script> 
</head> 
<body> 
<script> 
var sparql = new SPARQLWrapper("http://dbpedia.org/sparql"); 
sparql.setQuery('select distinct ?Concept where {[] a ?Concept} LIMIT 100'); 
sparql.query(function(json){ 
console.log(eval('(' + json + ')'); 
}); 
</script> 
</body> 
</html>

小例子:下载
Javascript 相关文章推荐
Javascript Function对象扩展之延时执行函数
Jul 06 Javascript
JavaScript调用客户端的可执行文件(示例代码)
Nov 28 Javascript
JS判断对象是否存在的10种方法总结
Dec 23 Javascript
Jquery的each里用return true或false代替break或continue
May 21 Javascript
html的DOM中Event对象onblur事件用法实例
Jan 21 Javascript
jquery中validate与form插件提交的方式小结
Mar 26 Javascript
input file上传 图片预览功能实例代码
Oct 25 Javascript
vue.js  父向子组件传参的实例代码
Oct 29 Javascript
jQuery实现购物车的总价计算和总价传值功能
Nov 28 jQuery
使用 Element UI Table 的 slot-scope方法
Oct 10 Javascript
JavaScript装箱及拆箱boxing及unBoxing用法解析
Jun 15 Javascript
vue操作dom元素的3种方法示例
Sep 20 Javascript
JS中不为人知的五种声明Number的方式简要概述
Feb 22 #Javascript
JS中令人发指的valueOf方法介绍
Feb 22 #Javascript
网页右键ie不支持event.preventDefault和event.returnValue (需要加window)
Feb 22 #Javascript
javascript 日期时间 转换的方法
Feb 21 #Javascript
JS关键字变色实现思路及代码
Feb 21 #Javascript
js数组Array sort方法使用深入分析
Feb 21 #Javascript
js自定义方法通过隐藏iframe实现文件下载
Feb 21 #Javascript
You might like
php面向对象全攻略 (十) final static const关键字的使用
2009/09/30 PHP
PHP 命令行工具 shell_exec, exec, passthru, system详细使用介绍
2011/09/11 PHP
解析php中获取url与物理路径的总结
2013/06/21 PHP
ThinkPHP表单自动提交验证实例教程
2014/07/18 PHP
laravel学习教程之关联模型
2016/07/30 PHP
javascript Split方法,indexOf方法、lastIndexOf 方法和substring 方法
2009/03/21 Javascript
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
2012/03/01 Javascript
js局部刷新页面时间具体实现
2013/07/04 Javascript
jquery仿百度百科底部浮动导航特效
2015/08/08 Javascript
javascript从作用域链谈闭包
2020/07/29 Javascript
jQuery实现的纵向下拉菜单实例详解【附demo源码下载】
2016/07/09 Javascript
微信小程序技巧之show内容展示,上传文件编码问题
2017/01/23 Javascript
JS前端开发判断是否是手机端并跳转操作(小结)
2017/02/05 Javascript
JS实现遍历不规则多维数组的方法
2018/03/21 Javascript
配置一个vue3.0项目的完整步骤
2019/04/26 Javascript
vue 公共列表选择组件,引用Vant-UI的样式方式
2020/11/02 Javascript
[02:59]DOTA2完美大师赛主赛事第三日精彩集锦
2017/11/25 DOTA
Python中的多重装饰器
2015/04/11 Python
Python的消息队列包SnakeMQ使用初探
2016/06/29 Python
python中闭包Closure函数作为返回值的方法示例
2017/12/17 Python
python调用API实现智能回复机器人
2018/04/10 Python
python删除文本中行数标签的方法
2018/05/31 Python
解决Python运行文件出现out of memory框的问题
2018/12/03 Python
pytz格式化北京时间多出6分钟问题的解决方法
2019/06/21 Python
django多个APP的urls设置方法(views重复问题解决)
2019/07/19 Python
使用python实现滑动验证码功能
2019/08/05 Python
django2.2安装错误最全的解决方案(小结)
2019/09/24 Python
pytorch 图像中的数据预处理和批标准化实例
2020/01/15 Python
python3+selenium获取页面加载的所有静态资源文件链接操作
2020/05/04 Python
python实现快速文件格式批量转换的方法
2020/10/16 Python
使用CSS3的box-sizing属性解决div宽高被内边距撑开的问题
2016/06/28 HTML / CSS
全球销量第一生发产品:Viviscal
2017/12/21 全球购物
医院检讨书范文
2014/02/01 职场文书
2014党员四风对照检查材料思想汇报
2014/09/17 职场文书
新学期家长寄语2016
2015/12/03 职场文书
拔河比赛队名及霸气口号
2015/12/24 职场文书