JSON-LD で RDF その1

# はじめに

[JSON-LD](http://json-ld.org/) は検索エンジン対策のための構造化データと思われがちですが、**JSON for Linking Data** という名が指すとおり、RDF に基づいた任意のリンクトデータを表現することができるフォーマットです。この文書では RDF データモデルを JSON-LD を使って記述する方法をざっくりと紹介します。

# 1. シナリオ

Turtle で書かれた SKOS によるシソーラスを JSON-LD で記述してみます。

```ndc10-lod.ttl
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .

<http://ndc10.linkedopendata.jp/#30> a skos:Concept ;
	skos:notation "30" ;
	skos:prefLabel "社会科学"@ja ;
	skos:broader <http://ndc10.linkedopendata.jp/#3> .

```

これは [日本十進分類法](https://ja.wikipedia.org/wiki/%E6%97%A5%E6%9C%AC%E5%8D%81%E9%80%B2%E5%88%86%E9%A1%9E%E6%B3%95) を @i2k さんが Turtle 化したものから抜粋したものです。もとの Turtle は <https://github.com/i2k/ndc10/blob/master/ndc10-lod.ttl> で公開されています。




# 2. 基本編


JSON-LD には記述を簡単にするための仕組みがいろいろとあるのですが、まずはそういった仕組みを使わずに記述してみましょう。


```json:basic.json
{
  "@id" : "http://ndc10.linkedopendata.jp/#30",
  "@type" : "http://www.w3.org/2004/02/skos/core#Concept",
  "http://www.w3.org/2004/02/skos/core#notation" : "30" ,
  "http://www.w3.org/2004/02/skos/core#prefLabel" : {
    "@language" : "ja",
    "@value" : "社会科学"
  } ,
  "http://www.w3.org/2004/02/skos/core#broader" : {
    "@id" : "http://ndc10.linkedopendata.jp/#3"
  }
}
```
ここではぼんやりと

* @**id** や @**type** などは特別な意味がありそうだ
* JSON のプロパティ名に直接 RDF 語彙の URI が記述されている
* JSON のプロパティ値は文字だったりさらに構造化されたオブジェクトだったり

といった雰囲気をつかんでみてください。


# 3. ネームスペース

いつも長い URL を書くのは大変です。もとの Turtle でも **skos:** プレフィックスを使って記法を省略しています。JSON-LD でもやってみましょう。こんなかんじになります。


```json:namespace.jsonld
{
  "@context" : {
    "skos" : "http://www.w3.org/2004/02/skos/core#"
  },
  "@id" : "http://ndc10.linkedopendata.jp/#30",
  "@type" : "skos:Concept",
  "skos:notation" : "30" ,
  "skos:prefLabel" : {
    "@language" : "ja",
    "@value" : "社会科学"
  } ,
  "skos:broader" : {
    "@id" : "http://ndc10.linkedopendata.jp/#3"
  }
}
```

どうやら @**context** というプロパティの中でネームスペースの定義ができるようです。**skos:broader** のように、短いプロパティ名が使えています。



# 4. デフォルトのデータ型

あるプロパティの値のデータ型や言語はいつも決まっているよ、という場合。


```json:range.jsonld
{
  "@context" : {
    "skos" : "http://www.w3.org/2004/02/skos/core#",
    "skos:broader" : {
      "@type" : "@id"
    },
    "skos:prefLabel" : {
      "@language" : "ja"
    }
  },
  "@id" : "http://ndc10.linkedopendata.jp/#30",
  "@type" : "skos:Concept",
  "skos:notation" : "30" ,
  "skos:prefLabel" : "社会科学" ,
  "skos:broader" : "http://ndc10.linkedopendata.jp/#3"
}
```

@**context** の中で **skos:broader** のデフォルトの値は URI だ、とか、 **skos:prefLabel** のデフォルトの言語は **ja** だ、といった定義ができるようです。
データ本体の各プロパティの値はすべて JSON 文字列になりました。だいぶすっきりしましたね。

# 5. データ定義とデータの分離

JSON-LD では外部の @**context** を参照する仕組みが用意されています。@**context** の値として URL (absolute or relative) を指定する、というものです。こんなかんじで二つのファイルに分離できます。

```json:http//example.org/context.jsonld
{
  "@context" : {
    "skos" : "http://www.w3.org/2004/02/skos/core#",
    "skos:broader" : {
      "@type" : "@id"
    },
    "skos:prefLabel" : {
      "@language" : "ja"
    }
  }
}
```


```json:data.jsonld
{
  "@context" : "http://example.org/context.jsonld",
  "@id" : "http://ndc10.linkedopendata.jp/#30",
  "@type" : "skos:Concept",
  "skos:notation" : "30" ,
  "skos:prefLabel" : "社会科学" ,
  "skos:broader" : "http://ndc10.linkedopendata.jp/#3"
}
```

いかがでしょうか？最後の **data.jsonld** は何の変哲もない JSON オブジェクト、といった見た目になりました。RDF の知識がない人でも作ったり・使えたりできそうなフォーマットです。

誰かが作った **context.jsonld** を参照して、いろいろな人が JSON-LD データを作ったり、それを使ったアプリを開発したり、といった世界が見えるかもしれません。

# 6. まとめ

* SKOS の RDF を例に JSON-LD で記述する方法を紹介しました
* RDF を直接書くと煩雑ですが、シンプルにする方法もあります
* context の共有化で RDF の知識がなくてもデータやアプリが作れる可能性