第32回 記法宣言の全容と文書実体の特殊事情 Page 2

川俣 晶
株式会社ピーデー
2005/4/2

記法宣言の用語定義

 次は、「記法」に引き続き、「記法宣言(Notation declarations)」の用語定義である。

[Definition: Notation declarations provide a name for the notation, for use in entity and attribute-list declarations and in attribute specifications, and an external identifier for the notation which may allow an XML processor or its client application to locate a helper application capable of processing data in the given notation.]

[定義:記法宣言は、記法の名前および外部識別子を提供し、この名前は、外部実体宣言および属性リスト宣言ならびに属性指定に用い、外部識別子は、与えられた記法のデータを処理できるプログラム(helper application)を、XMLプロセサまたは応用プログラムが探すために利用できる。]

 長くて分かりにくいので、分割して読んでいこう。まず、記法宣言は、記法の名前と外部識別子を提供することを確認しよう。この2つの情報を書き込むことが、記法宣言の目的である。具体的にこの2つの情報がどのように使われるのかというと、名前の方は外部実体宣言や、属性リスト宣言や、属性指定に使われることになる。これまで読んできた中で出現した記法についての名前を記述する場面では、この名前を使うことになる。一方、外部識別子は、与えられた記法のデータを処理できるプログラム探すために使用できる。具体的に探す方法は示されていない。

 ちなみに、外部識別子の中には、公開識別子のように、あらかじめ公的に名前が登録されているものがあり、それらを適切に分類すればプログラムを探す機能を標準化できるかもしれない。しかし、そもそもプログラムというのは環境依存という側面があるので、部分的にしか標準化できないのではないかと思う。

 さて、具体的にプログラムを探すのはだれかというと、XMLプロセッサか応用プログラムだという。ここで疑問に感じられるのは、応用プログラムはよいとして、XMLプロセッサの名前が出てくることである。XMLプロセッサが外部識別子からプログラムを探すということが妥当なのだろうか。XMLプロセッサは中立な存在であり、特定環境に依存するようなプログラムについての処理まで担うべきではないのではないだろうか。この疑問への答えは、後で述べるので、一時棚上げにして次を読もう。

記法宣言の生成規則

 次は、記法宣言の生成規則である。

[82]    NotationDecl    ::=    '<!NOTATION' S Name S (ExternalID | PublicID) S? '>' [VC: Unique Notation Name]
[83]    PublicID    ::=    'PUBLIC' S PubidLiteral

 ここには、[82] NotationDeclと[83] PublicIDという2つの生成規則が書かれている。その内容を順番に見ていこう。

 生成規則[82] NotationDeclは、記法宣言の生成規則そのものである。「<!」で始まっているのを見て分かるとおり、これは要素型宣言や属性リスト宣言の仲間であり、それらを記述できる個所に、これを記述することができる。そのことは、生成規則[29] markupdeclを振り返ることで確認できる。

[29]    markupdecl    ::=    elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment

 ここにはNotationDecl(記法宣言)と並んで、elementdecl(要素型宣言)、AttlistDecl(属性リスト宣言)、EntityDecl(実体宣言)、PI(処理命令)、Comment(コメント)が列挙されている。処理命令とコメントはさまざまな個所に記述可能でありやや性格が異なるが、そのほかの要素型宣言、属性リスト宣言、実体宣言の仲間として記法宣言があると思ってよいだろう。

 さて、具体的に生成規則[82] NotationDeclの内容を見ていこう。まず、文字列'<!NOTATION'があり、次に空白(S)、名前(Name)、空白(S)と続く。ここでの名前とはすでに出てきた記法の名前である。その後、生成規則[75] ExternalIDか生成規則[83] PublicIDのどちらか一方を記述し、最後に省略可能な空白(S?)を記述し、文字列'>'を記述して終わる。

 生成規則[75] ExternalIDは、「4.2.2 External Entities(4.2.2 外部実体)」にあった。その内容は以下のようなものであった。

[75]    ExternalID    ::=    'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral

 これについては、本連載の第24回「外部実体の諸問題を理解する」に詳しく説明しているので参照していただきたい。しかし、ここでは別の角度からこの生成規則について見ていきたいと思う。だが、これを見る前に、もう1つの生成規則を見ておこう。それと密接に関係のある話題である。

 ここに登場するもう1つ生成規則となる[83] PublicIDはさほど難しくない。文字列'PUBLIC'、空白(S)、生成規則[12] PubidLiteralと続くというだけの構造である。生成規則[12] PubidLiteralは、本連載の第6回「XMLにおける名前、トークン、リテラルデータ」で解説している。第24回にも関連する解説があるので併せて参照していただきたい。

 さて、いま一度、生成規則[82] NotationDeclに含まれる「(ExternalID | PublicID)」に立ち戻ろう。これは参照を展開して1つの生成規則に書き換えると、第一印象と異なる別の雰囲気を見せてくれるかもしれない。「(ExternalID | PublicID)」のExternalIDとPublicIDを、その定義の内容と入れ替えて書き直してみると以下のようになる。

('SYSTEM' S SystemLiteral
  | 'PUBLIC' S PubidLiteral S SystemLiteral
  | 'PUBLIC' S PubidLiteral)

 これはもっと簡潔に書き直すことができる。「'PUBLIC' S PubidLiteral」が2回登場しているが、これは1つにまとめることができる(これは、いわゆるリファクタリングに相当する操作かもしれない。EBNFでもリファクタリングがあり得るというのは面白い発見かもしれない。 EBNFの詳細については、第2回「XML勧告読解に必須のEBNF」を参照)。

('SYSTEM' S SystemLiteral
  | 'PUBLIC' S PubidLiteral (S SystemLiteral)?)

 さて、これを生成規則[75] ExternalIDと見比べていただきたい。果たしてどこが違うのだろうか。実は生成規則[75] ExternalIDと、生成規則[82] NotationDecl(の一部)の差は、「S SystemLiteral」の部分に省略を許さないか、あるいは許すかという差でしかない。

 このようなまわりくどい表記になっているのは、省略を許さない使い方が通常の使い方であり、省略を許すケースが例外的だからだろう。

 では、なぜ生成規則[75] ExternalIDでは許されない省略が、生成規則[82] NotationDeclでは許されるのだろうか。そのためには、SystemLiteral(システム識別子)の役割と、PubidLiteral(公開識別子)との違いを再確認する必要がある。本連載第24回では、以下のように記述した。

公開識別子は、通常、世界のどこでも一意に決まる特定の文字列となる。(中略)。それに対して、システム識別子(注)はそこで指定された場所(例えばURI)から情報を取得することが基本となる。

:本連載第24回の本文中では、「システム識別子」ではなく「外部識別子」として表記されているが、この文脈では「外部識別子=システム識別子+公開識別子」という関係になるため、用語を置換して表記している。うまく用語を整理できていないのは改善課題だと考えている)

 この文章が述べていることは、PubidLiteral(公開識別子)が単なる名前にすぎないのに対して、SystemLiteral(システム識別子)は具体的なリソースの所在を指定するために使われることである。XMLプロセッサは、SystemLiteral(システム識別子)の情報があれば、指定された対象のリソース(具体的にそれが何かはコンテキストによって異なる)を取得することができる。しかし、PubidLiteral(公開識別子)は単なる識別用の名前にすぎないので、名前と具体的なリソースの在りかを関連付ける情報抜きには、リソースを取得できない。

 これをまとめると、XMLプロセッサが対象のリソースを確実に手に入れるためには、SystemLiteral(システム識別子)が必須であることが分かる。生成規則[75] ExternalIDで、SystemLiteralの省略が許されないのは、これが妥当性の検証に使うリソースの指定などに使われる生成規則であるためである。つまり、XMLプロセッサ自身の仕事に必須の情報なので省略はできないのである。一方、生成規則[82] NotationDeclは記法宣言に使われるが、記法の情報はXMLプロセッサが処理することを義務づけられてはいない。もし、応用プログラムがPubidLiteral(公開識別子)から具体的なリソースの在りかを突き止めるための情報を持っているとすれば、XMLプロセッサは何もせず、ただPubidLiteral(公開識別子)を応用プログラムに渡すだけでよく、SystemLiteral(システム識別子)の情報はなくてもよい。

 このような差が、SystemLiteral(システム識別子)の省略の可否の差として現れていると考えるとよいだろう。(次ページへ続く)

2/3

 Index
やさしく読む「XML 1.0勧告」 第32回
記法宣言の全容と文書実体の特殊事情
  Page 1
・記法宣言と文書実体の概要
・「語ってもよろしいですかな?」
・記法宣言(Notation Declarations)
Page 2
・記法宣言の用語定義
・記法宣言の生成規則
  Page 3
・記法宣言の妥当性制約
・文書実体(Document Entity)


連載 やさしく読む「XML 1.0勧告」


XML & SOA フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日月間