RDFのシリアライゼーション形式
RDFはデータモデル(抽象的な概念)であり、そのモデルを具体的なテキストやファイルとして表現するには「シリアライゼーション形式」が必要です。本章では最も可読性の高いTurtle構文を中心に解説し、他の形式との比較も行います。
筆者は以前、RDF、TurtleやJSON-LD、およびIIIFマニフェストファイルなどの関係について整理しました。各シリアライゼーション形式の位置づけや関連性についてはRDF、TurtleやJSON-LD、およびIIIFマニフェストファイルなどの関係を理解するで解説しています。
主要なRDFシリアライゼーション形式は以下のとおりです。
| 形式 | 拡張子 | 特徴 |
|---|---|---|
| Turtle | .ttl | 可読性が高く、手書きに適する |
| N-Triples | .nt | 1行1トリプルの最もシンプルな形式 |
| JSON-LD | .jsonld | JSON互換でWeb開発者に馴染みやすい |
| RDF/XML | .rdf | XML形式。歴史的に最初の標準形式 |
| N-Quads | .nq | N-Triplesに名前付きグラフを追加した形式 |
| TriG | .trig | Turtleに名前付きグラフを追加した形式 |
Turtleの基本構文
Turtle(Terse RDF Triple Language)は、RDFを人間にとって読みやすく、書きやすい形式で表現するための構文です。SPARQLの構文はTurtleをベースとしているため、Turtleを理解することはSPARQLの学習にも直結します。
トリプルの記述
Turtleでは、トリプルを以下の形式で記述します。各トリプルはピリオド(.)で終わります。
<http://example.org/person/natsume_soseki> <http://xmlns.com/foaf/0.1/name> "夏目漱石" .
URIは山括弧(<>)で囲み、リテラルはダブルクォーテーション("")で囲みます。
プレフィックス宣言
毎回完全なURIを書くのは冗長です。Turtleでは、@prefix 宣言を用いてURIの名前空間に短い接頭辞を割り当てることができます。
@prefix ex: <http://example.org/person/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
ex:natsume_soseki foaf:name "夏目漱石" .
ex:natsume_soseki は <http://example.org/person/natsume_soseki> の省略形です。プレフィックスを使うことで、データの可読性が大幅に向上します。
よく使われるプレフィックスをまとめておきます。なお、プレフィックスとURIの対応を調べるには、prefix.ccが非常に便利です。筆者がprefix.ccを利用するで紹介しているとおり、このサービスを使えば標準的なプレフィックスを素早く確認できます。
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix schema: <http://schema.org/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@base 宣言
@base を使うと、相対URIの基準となるベースURIを指定できます。
@base <http://example.org/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<person/natsume_soseki> foaf:name "夏目漱石" .
<person/natsume_soseki> はベースURIと結合されて <http://example.org/person/natsume_soseki> として解釈されます。
省略記法
Turtleには、トリプルを効率よく記述するための省略記法がいくつか用意されています。
セミコロン(;)による述語の省略
同じ主語に対して複数の述語・目的語がある場合、セミコロンで区切ることで主語を省略できます。
@prefix ex: <http://example.org/person/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix schema: <http://schema.org/> .
ex:natsume_soseki foaf:name "夏目漱石"@ja ;
foaf:familyName "夏目" ;
foaf:givenName "金之助" ;
schema:birthDate "1867-02-09"^^xsd:date ;
schema:deathDate "1916-12-09"^^xsd:date .
これは以下の5つのトリプルと等価です。
ex:natsume_soseki foaf:name "夏目漱石"@ja .
ex:natsume_soseki foaf:familyName "夏目" .
ex:natsume_soseki foaf:givenName "金之助" .
ex:natsume_soseki schema:birthDate "1867-02-09"^^xsd:date .
ex:natsume_soseki schema:deathDate "1916-12-09"^^xsd:date .
カンマ(,)による目的語の省略
同じ主語・述語に対して複数の目的語がある場合、カンマで区切ることで主語と述語を省略できます。
@prefix ex: <http://example.org/person/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
ex:natsume_soseki foaf:knows ex:masaoka_shiki ,
ex:mori_ogai ,
ex:takahama_kyoshi .
a キーワード
rdf:type(リソースの型を指定するプロパティ)は非常に頻繁に使われるため、Turtleでは a という短縮形が用意されています。
@prefix ex: <http://example.org/person/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
ex:natsume_soseki a foaf:Person ;
foaf:name "夏目漱石"@ja .
a foaf:Person は rdf:type foaf:Person と等価です。
省略記法の組み合わせ
セミコロン、カンマ、a キーワードを組み合わせることで、複雑なデータを簡潔に記述できます。
@prefix ex: <http://example.org/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix schema: <http://schema.org/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
ex:book/wagahai a schema:Book ;
dcterms:title "吾輩は猫である"@ja ,
"I Am a Cat"@en ;
dcterms:creator ex:person/natsume_soseki ;
dcterms:issued "1905"^^xsd:gYear ;
dcterms:language "ja" ;
dcterms:subject ex:concept/japanese_literature ,
ex:concept/meiji_era .
空白ノードの記法
空白ノードはTurtleでは _: の後にローカル名を付けて表記するか、角括弧 [] を使って無名で記述できます。
# _: を使う方法
ex:person/tanaka schema:address _:addr1 .
_:addr1 schema:postalCode "100-0001" ;
schema:addressRegion "東京都" ;
schema:addressLocality "千代田区" .
# [] を使う方法(同じ意味)
ex:person/tanaka schema:address [
schema:postalCode "100-0001" ;
schema:addressRegion "東京都" ;
schema:addressLocality "千代田区"
] .
コレクション(リスト)
RDFにはリスト構造を表現するためのコレクション(Collection)という仕組みがあります。Turtleでは丸括弧 () で記述します。
ex:book/wagahai dcterms:subject ( ex:concept/cat ex:concept/teacher ex:concept/meiji ) .
実践的なTurtleの例
筆者がOmeka Sに語彙を登録する際には、Turtleファイルを実際に読み解く必要がありました。たとえば、Omeka SにPROV-Oオントロジーを登録する方法では、PROV-Oの語彙定義がTurtle形式で提供されており、その構造を理解してOmeka Sに登録する手順を紹介しています。
書誌データの記述
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix schema: <http://schema.org/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix ndl: <http://id.ndl.go.jp/auth/entity/> .
@prefix wd: <http://www.wikidata.org/entity/> .
<http://example.org/book/kokoro>
a schema:Book ;
dcterms:title "こころ"@ja ;
dcterms:creator <http://example.org/person/natsume_soseki> ;
dcterms:issued "1914-04-20"^^xsd:date ;
dcterms:publisher "岩波書店" ;
dcterms:language "ja" ;
schema:isbn "978-4-00-310101-5" ;
schema:numberOfPages "384" ;
rdfs:seeAlso wd:Q1196954 ;
rdfs:seeAlso ndl:00000051 .
<http://example.org/person/natsume_soseki>
a foaf:Person ;
foaf:name "夏目漱石"@ja ;
foaf:name "Natsume Sōseki"@en ;
schema:birthDate "1867-02-09"^^xsd:date ;
schema:deathDate "1916-12-09"^^xsd:date ;
schema:birthPlace <http://dbpedia.org/resource/Tokyo> ;
owl:sameAs wd:Q1195 ;
owl:sameAs ndl:00054222 .
この例では、rdfs:seeAlso で関連するリソース(Wikidata、国立国会図書館典拠データ)へのリンクを張り、owl:sameAs で同一人物を指す異なるURIを結びつけています。これがLinked Dataの実践です。
N-Triples
N-Triplesは、RDFの最もシンプルなシリアライゼーション形式です。1行に1つのトリプルを記述し、プレフィックスや省略記法は一切使いません。
N-Triplesは冗長ですが、パースが容易であるため、大量のRDFデータの一括処理やストリーム処理に適しています。行単位で処理できるため、sort や grep などのUNIXコマンドでの操作も可能です。
JSON-LD
JSON-LD(JSON for Linked Data)は、JSON形式でRDFデータを記述するための仕様です。Web開発者にとって馴染みのあるJSON構文をそのまま使えるため、Webアプリケーションとの統合に適しています。
{
"@context": {
"foaf": "http://xmlns.com/foaf/0.1/",
"schema": "http://schema.org/",
"dcterms": "http://purl.org/dc/terms/",
"name": "foaf:name",
"birthDate": "schema:birthDate",
"title": "dcterms:title"
},
"@id": "http://example.org/person/natsume_soseki",
"@type": "foaf:Person",
"name": "夏目漱石",
"birthDate": "1867-02-09",
"schema:author": {
"@id": "http://example.org/book/wagahai",
"@type": "schema:Book",
"title": "吾輩は猫である"
}
}
JSON-LDの特徴は @context の存在です。@context は、JSONのキーが実際にはどのURIに対応するかを定義します。これにより、通常のJSONとしても、RDFデータとしても解釈できる「二重の読み方」が可能になります。
IIIFのマニフェストファイルもJSON-LD形式で記述されており、デジタルアーカイブの分野ではJSON-LDは広く使われています。筆者はRDF、TurtleやJSON-LD、およびIIIFマニフェストファイルなどの関係を理解するでこれらの関係を整理しています。
また、DydraでのJSON-LDシリアライゼーションの挙動について調査した経験もあります。RDFストアによってJSON-LDの出力形式が異なる場合があるため、注意が必要です。詳しくはDydra JSON-LDシリアライゼーションの挙動と回避策をご覧ください。
シリアライゼーション形式の変換
異なるシリアライゼーション形式間の変換は、実務上よく発生する作業です。筆者はEASY RDFを用いてJSON-LDのデータをRDF/XMLやTurtleに変換してみるで、EASY RDFライブラリを使った変換方法を紹介しています。
RDF/XML
RDF/XMLは、RDFの最初の標準シリアライゼーション形式です。XML構文を用いてRDFトリプルを記述します。
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:schema="http://schema.org/">
<foaf:Person rdf:about="http://example.org/person/natsume_soseki">
<foaf:name xml:lang="ja">夏目漱石</foaf:name>
<schema:birthDate rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1867-02-09</schema:birthDate>
<schema:author>
<schema:Book rdf:about="http://example.org/book/wagahai">
<schema:name xml:lang="ja">吾輩は猫である</schema:name>
</schema:Book>
</schema:author>
</foaf:Person>
</rdf:RDF>
RDF/XMLは歴史的に広く使われてきましたが、XML構文の冗長さから、現在では新規にデータを記述する際にはTurtleやJSON-LDが好まれる傾向にあります。ただし、既存のシステムやツールではRDF/XMLが標準入出力形式になっている場合も多いため、読み方は理解しておくと良いでしょう。
形式の比較と使い分け
| 観点 | Turtle | N-Triples | JSON-LD | RDF/XML |
|---|---|---|---|---|
| 可読性 | 高い | 低い | 中程度 | 低い |
| 手書きのしやすさ | 最も書きやすい | 冗長 | JSON経験者には容易 | 冗長 |
| パース速度 | 中程度 | 最速 | 中程度 | 遅い |
| Web親和性 | 低い | 低い | 最も高い | 中程度 |
| ツールの対応 | 広い | 広い | 広い | 広い |
| 主な用途 | 手書き、学習 | バッチ処理 | Web API、SEO | レガシーシステム |
データを手書きで記述する場合や学習目的ではTurtleが最適です。Webアプリケーションとの統合にはJSON-LD、大量データの処理にはN-Triplesが適しています。
まとめ
本章では、RDFの主要なシリアライゼーション形式を学びました。重要なポイントを振り返ります。
- TurtleはRDFの最も可読性が高い形式で、プレフィックス宣言やセミコロン・カンマによる省略記法が使える
aキーワードはrdf:typeの省略形- N-Triplesは1行1トリプルの最もシンプルな形式で、バッチ処理に適する
- JSON-LDはJSON互換のRDF形式で、
@contextによりJSONキーとURIの対応を定義する - RDF/XMLは歴史的な標準形式だが、現在は他の形式が好まれる傾向にある
- Turtleの構文はSPARQLの基礎となるため、しっかり理解しておくことが重要
次章では、いよいよSPARQLの基本構文を学びます。Turtleで記述されたRDFデータに対して、どのようにクエリを発行するのかを見ていきましょう。