RELAX NG - プロバイダはASAHIネット|料金、接続

XMLのスキーマ書法(2)
村田 真
日本IBM(株)東京基礎研 / 国際大学
スキーマ言語
DTD, W3C XML Schema, RELAX NG
DTDの制定


W3CがXML 1.0の一部として制定した
SGML(XMLの原型)以来の長い歴史
DTDの構文

要素型宣言
<!ELEMENT doc (sec*)>

属性リスト宣言
<!ATTLIST doc
version CDATA #REQUIRED
year CDATA 1999
>
DTDの問題点





独自の奇妙な構文
拡張性の欠如
構文解析がしにくく、ツールが作りにくい
名前空間が扱えない
データ型がない
W3C XML Schemaの制定


W3Cが2001年に制定した勧告
Part 0, 1, 2の三部構成であり、
総計400ページ



Part 0: 入門
Part 1: 構造
Part 2: データ型
主な機構






単純型(データ型)
複合型 = 内容モデル + 属性宣言
継承(三種類)
要素宣言(タグ名を型に関連付ける)
属性宣言(属性名を単純型に関連付ける)
名前空間とモジュール化のための機構
W3C XML Schemaの複合型
<xsd:complexType name="Address" >
<xsd:sequence>
<xsd:element name="city" type="xsd:string" />
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country"
type="xsd:NMTOKEN "
use="fixed " value="US"/>
</xsd:complexType>
W3C XML Schemaの問題点


きわめて複雑
実装はいくつか存在するが,相互運用性
に問題がある


OOXMLのスキーマはMicrosoftの実装でしか
動かない
基盤となる数学理論がない
RELAX NGの制定


OASISのRELAX NG技術委員会とISO/IEC
JTC1 SC34委員会
ISO/IEC 19757-2
木正規文法



文字列言語ではなく木言語を使う
スキーマは木正規文法である
生成規則は、n ::= a < exp > の形である




n
非終端記号
a
終端記号
exp
非終端記号からなる正規表現
XML文書はsentenceである
Chomsky階層
木言語
文字列言語
Context-Free
Context-Free
Regular
Regular
Local
Local
木正規言語理論のもたらす利点

木オートマトンによる検証



数学的に厳密
小さな検証器
ブール演算が可能

スキーマの共通集合・和集合・差集合
Atom
デモ


ブログとAtomフィードの例
Atom使用アプリのデモ(はてな、Firefox)
Atomスキーマ

RFC 4287
Atomのスレッド拡張(RFC
4685)


ブログ記事のスレッド、ブログのトラック
バックによる関係を示す。
拡張部分





in-reply-to要素
rel="replies"のatom:link
total要素
thr:count属性
thr:updated属性
問題点


スレッド拡張のスキーマは、Atom本体のス
キーマから呼ばれていない。
Atomフィード全体をAtom本体スキーマに
照らして検証しても、拡張部分は検証され
ない。
スキーマのカスタマイズ方法

既存スキーマを直接編集する


既存スキーマが改版されたとき、メンテナンス
が困難。
既存スキーマを読み込んだ上で書き換え
るスキーマを作る

テクニックを要する(とくにDTD)
方法1: 置き換え

既存スキーマの定義文を、別の定義文で
置き換える。どのスキーマ言語でも利用で
きる。
例
include "foo.rnc" {
foo = bar
}

foo.rncにあったfooの定義文は無視さ
れ、こちらの定義が用いられる。
方法2: 組み合わせ

既存スキーマの定義文を生かしつつ、新し
い定義文と組み合わせる。RELAX NGでの
み利用できる。
例1
include "foo.rnc"
foo |= bar
}

foo.rncにあったfooの定義文と、新しい
定義文を、 choice(選択)で組み合わせ
る。
例2
include "foo.rnc"
foo &= bar
}

foo.rncにあったfooの定義文と、新しい
定義文を、 interleave(順不同)で組
み合わせる。
スキーマのスタイル



スキーマ書法にはいくつかのスタイルがあ
る。
どんな単位で定義文を書くかが各スタイル
によって異なる。
どのスタイルを採用するかによって、再利
用性・保守性・可読性は大きく変わる。
有力なスキーマスタイル




Russian Doll(定義文をできるだけ分割しな
い)
Salami Slice(要素・属性が現れると定義文
を分割する)
Venetian Blind(要素・属性の内容が現れ
ると定義文を分割する)
Garden of Eden(Salami SliceとVenetian
Blindの混合)
XML文書例

<foo>
<bar>
<baz1>1</baz1>
<baz2>2</baz2>
<baz3>3</baz3>
</bar>
<sat>
<baz1>1</baz1>
<baz2>2</baz2>
<baz3>3</baz3>
</sat>
<mas>
<baz1>1</baz1>
<baz2>2</baz2>
<baz3>3</baz3>
</mas>
</foo>
Russian Doll


トップレベルでは、要素定義がひとつだけ存在する。他の定義は、す
べてそのなかに埋め込まれる。
default namespace = ""
start =
element foo {
element bar {
element baz1 {
element baz2 {
element baz3 {
},
element sat {
element baz1 {
element baz2 {
element baz3 {
},
element mas {
element baz1 {
element baz2 {
element baz3 {
}
}
xsd:integer },
xsd:integer },
xsd:integer }
xsd:integer },
xsd:integer },
xsd:integer }
xsd:integer },
xsd:integer },
xsd:integer }
Salami Slice



要素定義を用い、内容定義は用いない。要素定義に内
容定義を埋め込む。
default namespace = ""
start = element foo { bar, sat, mas }
bar = element bar { baz1, baz2, baz3 }
sat = element sat { baz1, baz2, baz3 }
mas = element mas { baz1, baz2, baz3 }
baz1 = element baz1 { xsd:integer }
baz2 = element baz2 { xsd:integer }
baz3 = element baz3 { xsd:integer }
SGML時代からの伝統に基づいたスキーマ(Docbook,
TEI, XHTML2など)では、Salami Sliceを原則として採用
している。
Venetian Blind


内容定義を用い、要素定義は用いない。内容定義に要
素定義を埋め込む。
default namespace = ""
start = element foo {foo.content}
foo.content =
element bar { bsm.content },
element sat { bsm.content },
element mas { bsm.content }
bsm.content =
element baz1 { xsd:integer },
element baz2 { xsd:integer },
element baz3 { xsd:integer }

最近のスキーマではVenetian Blindを採用して
いるものがある。
Garden of Eden



要素定義と内容定義の両方を用いる。要素定義には内
容定義を埋め込まない。
default namespace = ""
start = element foo {foo.content}
foo.content = bar, sat, mas
bar = element bar { bsm.content }
sat = element sat { bsm.content }
mas = element mas { bsm.content }
bsm.content = baz1, baz2, baz3
baz1 = element baz1 { xsd:integer }
baz2 = element baz2 { xsd:integer }
baz3 = element baz3 { xsd:integer }
最近のスキーマではGarden of Edenを採用しているも
のがある(Universal Business Languageなど)。
どのスタイルを採用するか(1)

Russian Doll




簡明
カスタマイズ困難
冗長性あり
Salami Slice



伝統あるスタイルで、比較的理解しやすい
カスタマイズ可能
冗長性あり
どのスタイルを採用するか(2)

Venetian Blind




比較的理解しにくい
カスタマイズ可能
冗長性はさほどない
Garden of Eden



直感的でなく、理解しにくい
カスタマイズはきわめて容易
冗長性はない
問題




Atom本来のスキーマをそのまま用いて、
threading拡張スキーマを呼び出すようにカスタ
マイズせよ。
Atom本来のスキーマを拡張しやすいように書き
直せ。
書き直したスキーマをカスタマイズして、
threading拡張スキーマを呼び出せ。
Threading以外の拡張について、スキーマを作
成し、Atomスキーマ(書き直したもの)をカスタマ
イズして複数の拡張を同時に呼び出せ。
参考文献



Atom解説, http://www.witha.jp/Atom/
Bob DuCharme, “Your schema and the
industry-standard schema”,
http://www.idealliance.org/proceedings
/xml05/abstracts/paper30.HTML
RELAX NG入門、
http://www.kohsuke.org/relaxng/tutoria
l.ja.html