前言 自由百科全書不只應可以自由編寫,更應該可以自由取得。
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-Leeing
SticStic 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 distinct ?Concept where {[] a ?Concept} LIMIT 100
其中空格轉成。
實作細節 •跨域
我們可以透過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>} <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. 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(); >xhr = null; <BR>},0); <BR>} <BR>} <BR>xhr.send(this.queryPart); <BR>} </script>
}
return SPARQLWrapper
; }));
複製程式碼 程式碼如下:
>