Javascript实现关联数据(Linked Data)查询

系统 2287 0

前言

自由百科全书不仅仅应当可以自由编写,而更应该可以自由获得。

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查询(最好FQ,没FQ查询经常失败,不太明白为什么= =)。 

不过这种查询最终返回结果是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 %20 where %20 {[] %20 a %20 ?Concept} %20 LIMIT %20 100

其中空格被转成%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(
      
      
        json
      
      
        );
});

      
      
        </
      
      
        script
      
      
        >
      
      
        </
      
      
        body
      
      
        >
      
      
        </
      
      
        html
      
      
        >
      
    

 

小例子

http://pan.baidu.com/share/link?shareid=293219&uk=855675565

 

修订记录

  • 修正关于跨域的错误 2003.2.21

 

Javascript实现关联数据(Linked Data)查询


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论