Excel の WEBSERVICE 関数で SPARQL その1

Excel の WEBSERVICE 関数を使って SPARQL を実行し、必要なデータを取得する方法を紹介します。この記事で紹介する方法は [DBpedia Japanese](http://ja.dbpedia.org/) の SPARQL Endpoint を使用しています。

# 1. シナリオ

都道府県のリストに知事の名前を追加せよ、というお題が出ました。

![image](https://qiita-image-store.s3.amazonaws.com/0/82494/eef980b6-42dd-12cc-b2d1-995d806a88f6.png)

うまくいったら次は都道府県の木・花・鳥、知事のフリガナ、誕生日など思いつきでいろんなデータを追加していきたいみたいです。

# 2. 手順

**B2** セルに以下の関数をコピーします

```B2.
= FILTERXML(WEBSERVICE("http://ja.dbpedia.org/sparql?query=" & ENCODEURL("select * where {<http://ja.dbpedia.org/resource/" & A2 & "> <http://ja.dbpedia.org/property/知事> ?x } ")),"//binding/*")
```

以下のように値が取得できていたらまずは成功です

![image](https://qiita-image-store.s3.amazonaws.com/0/82494/2e5726f8-4727-d4f5-9d15-419d09036127.png)


**B2** を **B3** 以下にコピーすれば完了です

![image](https://qiita-image-store.s3.amazonaws.com/0/82494/0c828199-de8c-5907-d422-f92e0f6163b4.png)

なにかの拍子に再計算などが起こると意図しない負荷が発生するので、B 列を他の列に値コピーするなどの後処理がおすすめです。

# 3. 解説

各セルでは以下のような手順で処理が行われています

### a) 都道府県名を URI に変換

```
= "http://ja.dbpedia.org/resource/" & {都道府県名}
```

単純な文字の連結で地名を DBpedia Japanese の URI に変換しています。北海道の場合には以下のような URI です。

* <http://ja.dbpedia.org/resource/北海道>

都道府県名の場合には http://ja.dbpedia.org/resource/ を付与するだけで変換が済んでしまいますが、市区町村名などの場合にはもう少し複雑な処理が必要です。

### b) SPARQL クエリーを構築

```
= "select * where { <" & {URI} & "> <http://ja.dbpedia.org/property/知事> ?x }
```

文字連結によって、都道府県の URI から知事の URI を取得するための SPARQL Query を作ります。実体はこのようなクエリーになっています。

``` sparql.rq
select * where {
  <http://ja.dbpedia.org/resource/北海道> <http://ja.dbpedia.org/property/知事> ?x 
}
```

**北海道** の **知事** を **?x** に代入して取得しているんだな、と理解してもらえればまずは OK です。


### c) SPARQL Endpoint にアクセスするための URL を構築

```
= "http://ja.dbpedia.org/sparql?query=" & ENCODEURL({SPARQL})
```

**ENCODEURL関数** と文字連結によって以下のような URL を生成しています。この URL は DBpedia Japanese の SPARQL Endpoint に対してクエリーを送り、レスポンスを得るためのものです。

* <http://ja.dbpedia.org/sparql?query=select%20%2A%20where%20%7B%3Chttp%3A%2F%2Fja.dbpedia.org%2Fresource%2F%E5%8C%97%E6%B5%B7%E9%81%93%3E%20%3Chttp%3A%2F%2Fja.dbpedia.org%2Fproperty%2F%E7%9F%A5%E4%BA%8B%3E%20%3Fx%20%7D%20>

一般的なウェブブラウザでアクセスすると HTML が表示されるはずです。


### d) SPARQL クエリーを実行して結果を取得

```
= WEBSERVICE({URL})
```

**WEBSERVICE関数** を使って  SPARQL Endpoint に対してリクエストを送り、レスポンスを取得します。以下のような XML が取得されるはずです。

```sparql.xml
<sparql xmlns="http://www.w3.org/2005/sparql-results#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/sw/DataAccess/rf1/result2.xsd">
 <head>
  <variable name="x"/>
 </head>
 <results distinct="false" ordered="true">
  <result>
   <binding name="x"><uri>http://ja.dbpedia.org/resource/高橋はるみ</uri></binding>
  </result>
 </results>
</sparql>
```



### e) 実行結果をパースして必要な値をとりだす

```
= FILTERXML({XML},"//binding/*")
```

**FILTERXML 関数** を使って XML 文字列から必要な値を取り出します。ここでは **binding** 要素の配下の要素を取得するようにしています。この処理によって ```http://ja.dbpedia.org/resource/高橋はるみ``` が取得されることになります。


# 4. 次のステップ

### 別のプロパティの取得

今回の例は知事でしたが、それ以外にプロパティを取得してみましょう。使用できるプロパティは主語となっている <http://ja.dbpedia.org/resource/北海道> のリンク先で確認することができます。

### 別の主語に対するプロパティの取得

今回の例は都道府県でしたが DBpedia Japanese には他にもさまざまなデータが含まれています。主語になる URI を色々と変更して、データを取得してみましょう。

### 高度な SPARQL の実行

今回の例は主語と述語を指定すると結果となる目的語を返すという単純なものです。SPARQL ではもっと高度なクエリーを書くこともできます。挑戦してみましょう。

### Excel ワークシート関数

毎回長い関数をコピーするのが面倒な場合は、Excel のワークシート関数として定義してしまう、というのもひとつの方法です。


# 5. まとめ

* セルの値を元に SPARQL Endpoint からデータを取得する方法を紹介しました
* 手持ちのデータをうまく DBpedia の URI に関連付けることができれば、そこを起点にデータを取得することができます