第24回 外部実体の諸問題を理解する Page 2

川俣 晶
株式会社ピーデー
2004/8/6

外部実体の定義

 話を本筋に戻そう。XMLに含まれる難しい問題は、何も定義されないものへの参照だけではない。URIを使用するほかの多くの技術と同様、XMLにも相対的なURI参照の起点などの問題が含まれ、今回読んでいく範囲内に出てくる。

 さて、ここでは「4.2.2 External Entities(4.2.2 外部実体)」について読んでいこう。これは、「4.2 Entity Declarations(4.2 実体宣言)」の一部であり、実体宣言の中で特に外部実体の宣言について扱う。これに対して内部実体についての宣言は、前回読んだ「4.2.1 Internal Entities(4.2.1 内部実体)」に記述されていた。

 ここでは、まず、External Entity(外部実体)という用語の定義から始まる。

[Definition: If the entity is not internal, it is an external entity, declared as follows:]
[定義:内部実体でない実体は外部実体であって、次のとおりに宣言する。]

 外部実体とは「内部実体でない実体」という定義は、内部実体を把握していないと理解できず、分かりにくい。内部実体は、すでに以下のような定義が与えられていた。

実体の定義がEntityValueのとき、これを内部実体という。

 この文章の意味を正しく把握するために、もう一度、前回の生成規則を振り返ってみよう。

Entity Declaration
[70]    EntityDecl    ::=    GEDecl | PEDecl
[71]    GEDecl    ::=    '<!ENTITY' S Name S EntityDef S? '>'
[72]    PEDecl    ::=    '<!ENTITY' S '%' S Name S PEDef S? '>'
[73]    EntityDef    ::=    EntityValue| (ExternalID NDataDecl?)
[74]    PEDef    ::=    EntityValue | ExternalID

 ここで、生成規則[70] EntityDeclが実体宣言そのものに対応する。生成規則[71] GEDeclが一般実体宣言、生成規則[72] PEDeclがパラメタ実体宣言、生成規則[73] EntityDefが実体の定義、生成規則[74] PEDefがパラメタ実体の定義となる。そして、EntityValueの参照は、生成規則[73] EntityDefと生成規則[74] PEDefに出現する。この2つの生成規則には、EntityValueを参照するほかにも選択肢が示されている。つまり、「内部実体でない実体は外部実体」という言葉が意味するところは、この2つの生成規則でEntityValueの参照ではないものが使用された場合が外部実体であることを示しているわけである。

 では具体的に、それは何か。生成規則[73] EntityDefでは(ExternalID NDataDecl?)がそれに当たる。生成規則[74] PEDefではExternalIDがそれに当たる。ここに出てくる2つの生成規則、ExternalIDとNDataDeclは以下に定義されているわけである。これこそが、外部実体宣言の核心となる生成規則である。

External Entity Declaration
[75]    ExternalID    ::=    'SYSTEM' S SystemLiteral
      | 'PUBLIC' S PubidLiteral S SystemLiteral
[76]    NDataDecl    ::=    S 'NDATA' S Name [VC: Notation Declared]

外部実体宣言の生成規則(ExternalID)

 まず生成規則[75] ExternalIDだが、これは2つの書式のどちらか1つとなる。1つは、'SYSTEM'という文字列、空白文字、生成規則[11] SystemLiteralである。これは、外部識別子を示すものであり、以下のような内容であった。

[11] SystemLiteral    ::=    ('"' [^"]* '"') | ("'" [^']* "'")

 これは、本連載の「第6回 XMLにおける名前、トークン、リテラルデータ」で読んだ生成規則である。引用符「"」または「'」でくくった引用符自身を含まない任意の文字列である。例えば、"abc"や'abc'といった文字列が、この生成規則にマッチする。しかし、"Let's Go!"はOKだが、'Let's Go!'はくくる引用符と同じ文字を使うことができないため、不可である。この生成規則には、パラメタ実体参照も一般実体参照も含まれないので、"Cut&Paste"という文字列も記述できる。引用符でくくるという点で属性値も同じようなものだが、こちらは生成規則に実体参照が含まれるので、"Cut&amp;Paste"というように記述してやる必要があり、同じにはならない。

 以上を総合すると、生成規則[75] ExternalIDの前半は、例えば以下のような文字列にマッチする。

SYSTEM "http://www.atmarkit.co.jp/sample/uri"

 生成規則[75] ExternalIDの後半は、'PUBLIC'という文字列、空白文字、生成規則[12] PubidLiteral、空白文字、生成規則[11] SystemLiteralという並びとなる。生成規則[11] SystemLiteralは前半と共通だが、生成規則[12] PubidLiteralは共通していない。これも、本連載の第6回で読んだ生成規則である。生成規則[11] SystemLiteralと似ているが、使用できる文字が生成規則[13] PubidCharに記された文字に限定されている点が異なる。PubidCharは以下のような定義であった。

[13] PubidChar    ::=    #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]

 これは、半角空白、復帰、改行、半角アルファベットa〜zまでの小文字、大文字、半角数字の0〜9まで、そして、-'()+,./:=?;!*#@$_%のそれぞれの記号のいずれかを意味する。このように文字の種類が制約されているのは、これが公開識別子というものを指定するために使用されるからである。公開識別子はSGMLなどの関係でXML勧告とは別に定義が行われていて、厳密なものである。一方、生成規則[11] SystemLiteralの方は、システム依存のリソース参照を表記するものなので、使用してよい文字もそのシステムに依存する。つまりXML勧告では文字の種類を制約することができず、自由度が高い。

 以上を総合すると、生成規則[75] ExternalIDの後半は、例えば以下のような文字列にマッチする。

PUBLIC "ISO/IEC 10036/RA//Glyphs:10003290" "http://www.atmarkit.co.jp/sample/uri"
(表示の都合で折り返していますが、本来は1行です)

 さて、前半と後半、この2つはどう違うのだろうか。どちらも外部識別子(生成規則[11] SystemLiteral)を共通して持っている。意味のある相違点は、公開識別子(生成規則[12] PubidLiteral)を含むかどうかだけである。そこから当然想像可能なことではあるが、公開識別子を指定したい場合には後半の書式を使い、指定しない場合には前半の書式を使うことになるだろう。

 すでに述べたとおり、公開識別子はXML勧告の外部で定義されるものであって、それを使うべきかどうかの判断基準はXML勧告内では示されていない。ただ、公開識別子と外部識別子の性質の違いはここで付記しておく価値があるだろう。

 公開識別子は、通常、世界のどこでも一意に決まる特定の文字列となる。逆にいえば、ある文字列から、それが指し示すリソースを入手する方法は複数あってもよい。例えば、インターネット上に公開されたファイルを取得するような使い方があってもよいし、ローカルシステムにあらかじめ用意されたファイルにアクセスするような使い方があってもよい。結果が同じであれば、方法は問われないことになる。

 それに対して、外部識別子はそこで指定された場所(例えばURI)から情報を取得することが基本となる。問題は、後半の書式には、公開識別子と外部識別子の双方を記述することになり、それをどう使い分けるかである。これについては、後で規定が出てくるので、そこで確認していこう。

外部実体宣言の生成規則(NDataDecl)

 さて、まだ生成規則[76] NDataDeclが残っている。これは、記法データを宣言する書式である。内容は空白文字、'NDATA'という文字列、空白文字、生成規則[5] Nameという並びである。生成規則[5] Nameは要素や属性の名前に使われる生成規則である。つまり、記法の名前も、要素や属性の名前と同じルールで記述することになる。ここで、これは実体宣言の書式の一部であることを思い出しておこう。ここに記述される記法の名前は、そのような名前の記法を宣言するということではなく、すでに記法宣言によって宣言された記法の名前を参照する実体を宣言するためのものである。詳しくは「妥当性制約:Notation Declared(記法が宣言されていること)」の個所で解説する。

 さて、次は生成規則を補足する文章が続く。

If the NDataDecl is present, this is a general unparsed entity; otherwise it is a parsed entity.
NDataDeclが存在すれば、この実体は、一般解析対象外実体とし、そうでなければ、解析対象実体とする。

 この文章は注意深く読む必要がある。ここでは、unparsed entity(解析対象外実体)の前にgeneral(一般)という単語が付いているが、parsed entity(解析対象実体)の前には付いていないことに注意しよう。これは、いいかげんに書かれたために、付いたり付かなかったりしているものではない。

 この連載ではすでに一般実体、解析対象外実体、解析対象実体といった用語について読んできている。一般実体は文書内容の中で使用する実体で、反対の意味を持つのはパラメタ実体である。解析対象外実体は解析の対象とせず、あらゆるデータを扱うための実体。その反対の意味を持つ解析対象実体は内容を置換テキストとして文書内に取り込む実体である。

 さて、以上の知識を再確認してからこの文章をじっくりと吟味してみよう。生成規則[76] NDataDeclが記述できるケースは、生成規則[73] EntityDefである。これは一般実体の定義であるから、生成規則[76] NDataDeclが存在する場合は常に一般実体である。そして、生成規則[76] NDataDeclは記法データを宣言する書式であり、記法は常に解析対象外実体とともに使われるということを考えれば、生成規則[76] NDataDeclが存在することと一般解析対象外実体であることがイコールで結び付くことが分かるだろう。一方、生成規則[76] NDataDeclが存在しないケースは、一般実体を定義する生成規則[73] EntityDefで省略可能なNDataDeclが省略されたケースと、パラメタ実体を定義する生成規則[74] PEDefのケースがある。前者は一般実体だが、後者はパラメタ実体である。それ故に、general(一般)という単語が先頭には付かないことになり、ただ単に解析対象実体と記述されているわけである。

妥当性制約:Notation Declared

 次は、妥当性制約:Notation Declared(記法が宣言されていること)である。

Validity constraint: Notation Declared

The Name MUST match the declared name of a notation.
妥当性制約:Notation Declared(記法が宣言されていること)

Nameは、宣言した記法の名前とマッチしなければならない。

 この文章は、記法の扱いについての知識がないと混乱するかもしれない。この生成規則は、記法の指定を含む実体宣言についてのものである。宣言の中で使用される名前であるのに宣言した名前とマッチしなければならない、とはどういう意味だろうか。これは、実体の宣言と記法の宣言を混同したために起こった混乱といえる。記法を使用する場合は、まず「4.7 Notation Declarations(4.7 記法宣言)」で規定される記法宣言を行わねばならない。この記法宣言によって、記法が名前と関連付けられる。実体宣言の中では、記法に関連付けられた名前を記述することによって、具体的に使用する記法の種類を明示する。このように2段階を踏まなければ、記法を用いた実体を宣言することができない。つまり「Nameは、宣言した記法の名前とマッチしなければならない」とは、より具体的にいえば「Nameは、別途記法宣言によって宣言された記法の名前とマッチしなければならない」という意図を示しているのである。

 さて、まだ「4.2.2 External Entities(4.2.2 外部実体)」の途中ではあるが、今回はここまでである。今回は、実体宣言の中でも外部実体の宣言について読み始めたが、前回の内部実体と合わせて、両者の相違を確認しておくとよいだろう。次回は、「4.2.2 External Entities(4.2.2 外部実体)」の残りを読み切ってしまおう。次回の主役は、統一資源識別子(URI)である。外部のリソースを識別するために使用されるURIには、文字の別扱い(escape)や相対URIの基準点といった悩ましい問題があるが、XML 1.0勧告からもそれらに対して言及される。それらを確実に把握しつつ、外部実体への理解を深めていこう。(次回に続く)

2/2

 Index
やさしく読む「XML 1.0勧告」 第24回
外部実体の諸問題を理解する
  Page 1
・外部実体の概要
定義されないものへの参照

Page 2
・外部実体の定義

外部実体宣言の生成規則(ExternalID)
外部実体宣言の生成規則(NDataDecl)
妥当性制約:Notation Declared 


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


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

注目のテーマ

HTML5+UX 記事ランキング

本日月間