Heim >Web-Frontend >js-Tutorial >Javascript实现关联数据(Linked Data)查询及注意细节_javascript技巧

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

WBOY
WBOYOriginal
2016-05-16 17:41:411236Durchsuche
前言
自由百科全书不仅仅应当可以自由编写,而更应该可以自由获得。
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> <BR>} <BR>}(this, function(){ <BR>'use strict' <BR>function SPARQLWrapper(endpoint){ <BR>this.endpoint = endpoint; <BR>this.queryPart = ""; <BR>this.type = "json"; <BR>} <BR>SPARQLWrapper.prototype = { <BR>constructor: SPARQLWrapper, <BR>setQuery: function(query){ <BR>this.queryPart = "query=" + encodeURI(query); <BR>}, <BR>setType: function(type){ <BR>this.type = type.toLowerCase(); <BR>}, <BR>query: function(type, callback){ <BR>callback = callback === undefined ? type : this.setType(type) || callback; <BR>var xhr = new XMLHttpRequest(); <BR>xhr.open('POST', this.endpoint, true); <BR>xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); <BR>switch(this.type){ <BR>case "json": <BR>type = "application/sparql-results+json"; <BR>break; <BR>case "xml": <BR>type = "text/xml"; <BR>break; <BR>case "html": <BR>type = "text/html"; <BR>break; <BR>default: <BR>type = "application/sparql-results+json"; <BR>break; <BR>} <BR>xhr.setRequestHeader("Accept", type); <BR>xhr.onreadystatechange = function(){ <BR>if(xhr.readyState == 4){ <BR>var sta = xhr.status; <BR>if(sta == 200 || sta == 304){ <BR>callback(xhr.responseText); <BR>}else{ <BR>console && console.error("Sparql query error: " + xhr.status + " " + xhr.responseText); <BR>} <BR>window.setTimeout(function(){ <BR>xhr.onreadystatechange= new Function(); <BR>xhr = null; <BR>},0); <BR>} <BR>} <BR>xhr.send(this.queryPart); <BR>} <BR>} <BR>return SPARQLWrapper; <BR>})); <BR></script>

使用方法,例如需要查询:
select distinct ?Concept where {[] a ?Concept} LIMIT 100
则该页面为:
复制代码 代码如下:








<script> <BR>var sparql = new SPARQLWrapper("http://dbpedia.org/sparql"); <BR>sparql.setQuery('select distinct ?Concept where {[] a ?Concept} LIMIT 100'); <BR>sparql.query(function(json){ <BR>console.log(eval('(' + json + ')'); <BR>}); <BR></script>



Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn