RubyでRDFを構築してみる



RDFに関する雑な説明で、RDFについて説明しました。
http://qiita.com/eielh/items/deadb765ac994956f8a2

RubyでRDFをつくってみます。RDFに関するライブラリは[RDF.rb](http://ruby-rdf.github.io/)があります。

linkeddata gemをインストールするとだいたい必要なものが入るらしいです。

```
gem install linkeddata
```

必要最低限でよければ`rd`というgemで十分です。

```
gem install rdf
```

RDFはステートメントの集合で、ステートメントはSubject Predicate Objectの３つの要素で構成されます。
ステートメントをつくってみましょう。

```ruby
require 'rdf'

subject = RDF::URI.new("http://qiita.com")
predicate = "name"
object = "Qiita"

stmt = RDF::Statement.new(subject, predicate, object)
```

subjectはURIである必要がありましたね。

ステートメントの集合はグラフとよばれるものです。Graphにつめます。

```ruby
require 'rdf'

graph = RDF::Graph.new

subject = RDF::URI.new("http://qiita.com")
predicate = "name"
object = "Qiita"

graph << RDF::Statement.new(subject, predicate, object)
```

とても簡単ですね。JSON-LDで出力してみましょう。
[json-ld](https://github.com/ruby-rdf/json-ld) gemをつかいます。

```
gem install json-ld
```

```ruby
require 'rdf'
require 'json/ld'

graph = RDF::Graph.new

subject = RDF::URI.new("http://qiita.com")
predicate = "name"
object = "Qiita"

graph << RDF::Statement.new(subject, predicate, object)
graph.dump(:jsonld)
```

```出力
[
  {
    "@id": "http://qiita.com",
    "name": [
      {
        "@value": "Qiita"
      }
    ]
  }
]
```

実際に利用するJSON-LDを生成する場合は`graph.dump(:jsonld, standard_prefixes: true)`するほうがよいです。
しかし、この場合は空のオブジェクトが生成されてしまいます。

schema.orgのスキーマを利用してこの情報が何らかのものであることをしめしましょう。（データの型を宣言してあげて、データが持つフィールドも明確に示してあげる)

rdf-vocabを使うと既存のスキーマを利用しやすいです。

```
gem install rdf-vocab
```

```ruby
require 'rdf'
require 'json/ld'
require 'rdf/vocab'

graph = RDF::Graph.new

subject = RDF::URI.new("http://qiita.com")

graph << RDF::Statement.new(subject, RDF.type, RDF::Vocab::SCHEMA.Thing)
graph << RDF::Statement.new(subject, RDF::Vocab::SCHEMA.name, "Qiita")
graph.dump(:jsonld, standard_prefixes: true)
```

```出力
{
  "@context": {
    "schema": "http://schema.org/"
  },
  "@id": "http://qiita.com",
  "@type": "schema:Thing",
  "schema:name": "Qiita"
}
```

@contextは`http://schema.org/`をschemaって名前で扱うという宣言のようなものかとおもいます。

`schema:name`は本当は`http://schema.org/name`ですが省略してかけるわけです。
schema:Thingがこの情報の種類をしめしますが、その詳細は http://schema.org/Thing にかかれています。linkedですね。

当然このページもRDFになっています。 N-Triples形式で出力しておきます。

```
$  ruby -r linkeddata -e 'puts RDF::Graph.load("http://schema.org/Thing").dump(:ntriples)'
```

```出力
<http://schema.org/Thing> <http://www.w3.org/ns/rdfa#usesVocabulary> <http://schema.org/> .
<http://schema.org/Thing> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://schema.org/Thing> <http://www.w3.org/2000/01/rdf-schema#comment> "The most generic type of item."@en .
<http://schema.org/Thing> <http://www.w3.org/2000/01/rdf-schema#subClassOf> "rdfs:Class"@en .
_:g70339982402060 <http://www.w3.org/1999/xhtml/vocab#role> <http://www.w3.org/1999/xhtml/vocab#checkbox> .
<http://schema.org/additionalType> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Property> .
<http://schema.org/additionalType> <http://www.w3.org/2000/01/rdf-schema#label> "additionalType"@en .
<http://schema.org/additionalType> <http://schema.org/rangeIncludes> <http://schema.org/URL> .
<http://schema.org/additionalType> <http://www.w3.org/2000/01/rdf-schema#comment> "An additional type for the item, typically used for adding more specific types from external vocabularies in microdata syntax. This is a relationship between something and a class that the thing is in. In RDFa syntax, it is better to use the native RDFa syntax - the 'typeof' attribute - for multiple types. Schema.org tools may have only weaker understanding of extra types, in particular those defined externally."@en .
<http://schema.org/alternateName> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Property> .
<http://schema.org/alternateName> <http://www.w3.org/2000/01/rdf-schema#label> "alternateName"@en .
<http://schema.org/alternateName> <http://schema.org/rangeIncludes> <http://schema.org/Text> .
<http://schema.org/alternateName> <http://www.w3.org/2000/01/rdf-schema#comment> "An alias for the item."@en .
<http://schema.org/description> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Property> .
<http://schema.org/description> <http://www.w3.org/2000/01/rdf-schema#label> "description"@en .
<http://schema.org/description> <http://schema.org/rangeIncludes> <http://schema.org/Text> .
<http://schema.org/description> <http://www.w3.org/2000/01/rdf-schema#comment> "A short description of the item."@en .
<http://schema.org/image> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Property> .
<http://schema.org/image> <http://www.w3.org/2000/01/rdf-schema#label> "image"@en .
<http://schema.org/image> <http://schema.org/rangeIncludes> <http://schema.org/ImageObject> .
<http://schema.org/image> <http://schema.org/rangeIncludes> <http://schema.org/URL> .
<http://schema.org/image> <http://www.w3.org/2000/01/rdf-schema#comment> "An image of the item. This can be a URL or a fully described ImageObject."@en .
<http://schema.org/mainEntityOfPage> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Property> .
<http://schema.org/mainEntityOfPage> <http://www.w3.org/2000/01/rdf-schema#label> "mainEntityOfPage"@en .
<http://schema.org/mainEntityOfPage> <http://schema.org/rangeIncludes> <http://schema.org/CreativeWork> .
<http://schema.org/mainEntityOfPage> <http://schema.org/rangeIncludes> <http://schema.org/URL> .
<http://schema.org/mainEntityOfPage> <http://www.w3.org/2000/01/rdf-schema#comment> "Indicates a page (or other CreativeWork) for which this thing is the main entity being described.\n      \n      See background notes for details.\n       Inverse property: mainEntity."@en .
<http://schema.org/name> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Property> .
<http://schema.org/name> <http://www.w3.org/2000/01/rdf-schema#label> "name"@en .
<http://schema.org/name> <http://schema.org/rangeIncludes> <http://schema.org/Text> .
<http://schema.org/name> <http://www.w3.org/2000/01/rdf-schema#comment> "The name of the item."@en .
<http://schema.org/potentialAction> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Property> .
<http://schema.org/potentialAction> <http://www.w3.org/2000/01/rdf-schema#label> "potentialAction"@en .
<http://schema.org/potentialAction> <http://schema.org/rangeIncludes> <http://schema.org/Action> .
<http://schema.org/potentialAction> <http://www.w3.org/2000/01/rdf-schema#comment> "Indicates a potential Action, which describes an idealized action in which this thing would play an 'object' role."@en .
<http://schema.org/sameAs> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Property> .
<http://schema.org/sameAs> <http://www.w3.org/2000/01/rdf-schema#label> "sameAs"@en .
<http://schema.org/sameAs> <http://schema.org/rangeIncludes> <http://schema.org/URL> .
<http://schema.org/sameAs> <http://www.w3.org/2000/01/rdf-schema#comment> "URL of a reference Web page that unambiguously indicates the item's identity. E.g. the URL of the item's Wikipedia page, Freebase page, or official website."@en .
<http://schema.org/url> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Property> .
<http://schema.org/url> <http://www.w3.org/2000/01/rdf-schema#label> "url"@en .
<http://schema.org/url> <http://schema.org/rangeIncludes> <http://schema.org/URL> .
<http://schema.org/url> <http://www.w3.org/2000/01/rdf-schema#comment> "URL of the item."@en .
```

```
$ ruby -r linkeddata -e 'puts RDF::Graph.load("http://schema.org/name").dump(:ntriples)'
```

```
<http://schema.org/name> <http://www.w3.org/ns/rdfa#usesVocabulary> <http://schema.org/> .
<http://schema.org/name> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Property> .
<http://schema.org/name> <http://www.w3.org/2000/01/rdf-schema#comment> "The name of the item."@en .
<http://schema.org/name> <http://schema.org/rangeIncludes> <http://schema.org/Text> .
<http://schema.org/name> <http://schema.org/domainIncludes> <http://schema.org/Thing> .
_:g70096334315980 <http://www.w3.org/1999/xhtml/vocab#role> <http://www.w3.org/1999/xhtml/vocab#checkbox> .
```

楽しいですね！

DOT言語でも経由して簡単に視覚化する方法がありそうだけどしらべていない。