第33回 XML勧告への適合性を示すConformance Page 2

川俣 晶
株式会社ピーデー
2005/5/11

妥当性を検証するプロセッサおよび検証しないプロセッサ

 さて、「5 Conformance(5 適合性)」の次は、何の文章もなく次に「5.1 Validating and Non-Validating Processors(5.1 妥当性を検証するプロセッサおよび検証しないプロセッサ)」に進む。ここでは、表題にあるような2種類のXMLプロセッサが存在することと、それぞれが満たすべき条件について示されている。つまり、XML 1.0勧告に適合するXMLプロセッサの条件は2種類存在するわけである。実は、XMLプロセッサの条件を示す場合には、このどちらなのか、あるいは両方の機能を含むことを示す必要がある。

 では早速読んでいこう。まずは、XMLプロセッサの分類についてである。

Conforming XML processors fall into two classes: validating and non-validating.

適合XMLプロセサは、妥当性を検証するものおよび妥当性を検証しないものの2つに分類される。

 XMLの入門書などでは、よくXML文書を「整形式のXML文書」「妥当なXML文書」と分類しているが、その分類とこのXMLプロセッサの分類は必ずしも一致していない。つまり、「整形式のXML文書」を処理するプロセッサが「妥当性を検証しない」XMLプロセッサであり、「妥当なXML文書」を処理するプロセッサが「妥当性を検証する」XMLプロセッサである、というわけではない。実際には、「妥当性を検証しない」XMLプロセッサは「妥当なXML文書」も処理することができる。そのことは、厳密にいうと「整形式のXML文書」「妥当なXML文書」という分類が誤りであることを思い出せば分かるだろう。すべての「妥当なXML文書」は、同時に「整形式のXML文書」としての条件を満たしており、つまり「整形式のXML文書」でもあるのだ。それ故に、「妥当なXML文書」は「整形式のXML文書」でもあり、「妥当性を検証しない」XMLプロセッサで処理できる。なお、妥当性を検証するXMLプロセッサ(Validating processors)の用語定義は、2つ先の段落に含まれるので、具体的な定義はひとまず置いて先に進もう。

 次は、整形式制約についての規定である。

Validating and non-validating processors alike MUST report violations of this specification's well-formedness constraints in the content of the document entity and any other parsed entities that they read.

妥当性を検証するプロセサも妥当性を検証しないプロセサも、読み込んだ文書実体およびほかのすべての解析対象実体において、この規格の整形式制約への違反を報告しなければならない(MUST)。

 ここでは、まず2種類のXMLプロセッサのどちらも対象にしていることを確認しておこう。整形式制約に関する規定だからといって、妥当性を検証しないプロセッサだけに適用される規定というわけではない。そして、対象となる実体が文書実体と解析対象実体であることが示される。ここに解析対象外実体が含まれないのは、それがXML勧告の構文に従うことが求められていない実体である以上、当然のことといえる。

 そして、その手前に付いている「読み込んだ……」という部分をチェックしておこう。この規定は、あくまで読み込んだ実体にのみ適用され、読み込まなかった実体には適用されない。もちろん、読み込まなかった実体については、どんな処理も不可能であるから、当然の規定といえるが、あいまいさを少しでも減らすために明示しているのだろう。そして、これらの対象に対して、整形式制約への違反を報告する義務がXMLプロセッサに課せられていることが示されている。これはMUSTで記述されており、必須の要件である。

 次は、「妥当性を検証するXMLプロセッサ(Validating processors)」の用語定義である。

[Definition: Validating processors MUST, at user option, report violations of the constraints expressed by the declarations in the DTD, and failures to fulfill the validity constraints given in this specification.] To accomplish this, validating XML processors MUST read and process the entire DTD and all external parsed entities referenced in the document.

[定義:利用者の任意選択によっては、妥当性を検証するプロセサは、DTD内の宣言によって示された制約への違反と、この規格が規定する妥当性制約への違反とを、すべて報告しなければならない(MUST)。] これを実現するために、妥当性を検証するXMLプロセサは、DTD全体と文書内で参照されているすべての外部解析対象実体とを読み込んで処理しなければならない。

 この段落は2つの文章から成り立っているが、前半が「妥当性を検証するXMLプロセッサ(Validating processors)」の用語定義で、後半が通常の文章である。

 前半は、とても「妥当性を検証するプロセッサ」の用語定義とは読めないが、これが用語定義である。つまり、このような違反の報告義務を満たす機能を持ったXMLプロセッサが、「妥当性を検証するプロセッサ」ということである。どのような違反を報告する義務があるかといえば、それは2つある。1つは、DTD内の宣言への違反。これはDTDを記述した者が課した制約への違反である。もう1つは、妥当性制約への違反である。これは、XML勧告を書いた者たちが課した制約への違反である。これらへの違反はすべて報告しなければならない。一部だけを報告することは許されていない。

 ただし、この機能は、「利用者の任意選択」という言葉で示されるとおり、有効にすることも無効にすることもできなければならない。この選択が必須であることは、実際に運用することを考えてみれば分かるだろう。つまり、世の中には、この制約を満たすXML文書のほかに、満たさないXML文書(整形式であるだけのXML文書)も存在するのである。それを処理可能にするためには、たとえ妥当性を検証するXMLプロセッサであっても、DTDや妥当性に関する制約を適用しない選択肢が必要とされる。

 後半は、前の文で述べた機能を実現するために、読み込むことを義務づける対象を明確に規定する文章である。まず、文章の区切りが分かりにくいと思うのだが、この文章は『「DTD全体と文書内で」参照されているすべての外部解析対象実体と』と読むのではなく、『「DTD全体と」「文書内で参照されているすべての外部解析対象実体と」』と区切って読む。つまり、妥当性を検証するXMLプロセサは、「DTD全体」を読み込んで処理する義務と、「文書内で参照されているすべての外部解析対象実体」を読み込んで処理する義務をどちらも持つということである。

 さて、妥当性を検証するXMLプロセッサの次は、妥当性を検証しないプロセッサについての規定である。

Non-validating processors are REQUIRED to check only the document entity, including the entire internal DTD subset, for well-formedness. [Definition: While they are not required to check the document for validity, they are REQUIRED to process all the declarations they read in the internal DTD subset and in any parameter entity that they read, up to the first reference to a parameter entity that they do not read; that is to say, they MUST use the information in those declarations to normalize attribute values, include the replacement text of internal entities, and supply default attribute values.] Except when standalone="yes", they MUST NOT process entity declarations or attribute-list declarations encountered after a reference to a parameter entity that is not read, since the entity may have contained overriding declarations; when standalone="yes", processors MUST process these declarations.

妥当性を検証しないプロセサは、整形式であることを確認するために、DTDの内部サブセット全体を含めた文書実体を調べることだけが義務づけられている。[定義:文書の妥当性を確認する必要はないが、読み込んでいないパラメタ実体への参照が最初に起きるまでに読み込んだDTDの内部サブセットとパラメタ実体とに現れるすべての宣言を処理しなければならない。すなわち、属性値を正規化し、内部実体の置換テキストを取り込みデフォルトの属性値を与えるために、これらの宣言にある情報を使用しなければならない。] 実体の宣言は上書きされる可能性があるので、妥当性を検証しないプロセサは、読み込んでいないパラメタ実体への参照より後に現れた実体宣言および属性リスト宣言処理してはならないが、standalone="yes"のときは宣言を処理しなければならない。

 この段落は3つの文章から成り立っている。しかし、実は表面からは見えにくい部分で、非常にトリック的な構成を取っているので注意が必要である。ちなみに、JIS X 4159を読む場合には、このトリック的な部分が切り捨てられていて、存在そのものに気付くことができない。W3CのXML勧告をプリントアウトして読む場合も同じである。

 さて、最初の文から読み始めよう。最初の文には特に分かりにくいトリックはない。もちろん、見てのとおり妥当性を検証しないプロセッサについての規定である。ここでは、そのようなプロセッサが処理対象とするよう義務づけられているのは、文書実体だけだということが示されている。つまり、文書実体以外を処理することは義務づけられていない。そして、ここでいう文書実体とは、DTDの内部サブセット全体を含めるものであるとしている。つまり、内部サブセットについては、たとえ妥当性を検証しないプロセッサであっても単に読み飛ばすことが許されない。そこに書かれた内容を、最低限要求される機能を実現するために解釈する必要がある。なお、ここに出てくる「REQUIRED」という単語は、「RFC 2119 Key words for use in RFCs to Indicate Requirement Levels」によって、「MUST」と同等であることが示されている。

 余談だが、XMLの入門記事を軽く読んだプログラマが、妥当性を検証しないXMLプロセッサならすぐにでも作れるという第1印象を持ったとしても不思議ではない。しかし、実際に、片手間の短時間でちょいちょいと作り上げることはできない。その理由はここにある。

 大抵のXMLの入門記事では、整形式のXML文書ではDTDはなくてもよいと説明している。これは間違いではない。しかし、DTDがあってもよい、というのも事実である。そして、DTDの内部サブセットが存在する場合、そこに含まれる実体宣言などは、妥当性を検証しないXMLプロセッサにより解釈されることが期待できる。つまり、シンプルな実体宣言と実体参照などは、整形式のXML文書に書き込むことが可能なのである。

 このことは、逆にいえば、少なくともDTDの知識の一部を持たずに妥当性を検証しないプロセッサを開発することはできないことを意味する。たとえすべてではなくてもDTDを把握することと、それを適切に実装する手間が、第1印象から想定される手間に上乗せされ、思ったほど短時間ではXMLプロセッサを開発できないことになる(もっとも、その手間を含めて考えても、妥当性を検証しないプロセッサの開発は十分に軽い作業に分類できる)。

 さて、次は段落中の2番目の文である。この2文は「Process Declarations(処理宣言)」というキーワードの用語定義となっている。しかし、本文中にこの単語は出現しない。この定義の文章の中にも出現しないし(processだけが太文字になり定義対象の単語であることが暗示される)、本文中のほかの場所にも出現していない。つまり、極めてミステリアスな用語定義なのである。いかなるトリックが、このミステリアスな用語定義を構成しているかは、この後で詳しく説明を行う。

 この文章は、「;」の手前と後を分けて読んでみよう。まず手前は、妥当性を検証しないプロセッサについて、妥当性を確認することはないこと、DTDの中で特定の条件を満たす範囲のすべての宣言を処理すべきことが要求されている(REQUIRED)。ここで処理が要求される対象が、非常に限定的であることに注意を払っておこう。すべての宣言という言葉から受ける印象の強さとは裏腹に、極めてきつい制約が課せられているために、利用者サイドからはすべての宣言が処理されるという前提を取ることはできない。本当に限定的な条件下でのみ、確実に宣言は処理されると考える方が安全だろう。そして、どの宣言が処理されるかは、必須ではないが読み込むことも許される外部サブセットの存在により、XMLプロセッサの実装次第で変わる余地が残されている。

 では、「;」以後の後半の文章を見てみよう。ここは、前半の文章の規定をより具体的に説明したものである。妥当性を検証しないプロセッサがDTDを処理する理由として、以下の3つが示されている。

  • 属性値を正規化し
  • 内部実体の置換テキストを取り込み
  • デフォルトの属性値を与える

 いい換えれば、これらの処理は、妥当性を検証しないプロセッサでも行われる可能性があるということである。しかし、条件によって、「必ず行われる」ケースと、「XMLプロセッサの実装次第で行われることもある」ケースがあり得ることに注意が必要である。

 さて、最後の文に行こう。ここには、前の文で「読み込んでいないパラメタ実体への参照が最初に起きるまで」という条件が付けられている理由と、その例外事項について書かれている。つまり、宣言は上書き可能であるために、読み込んだ宣言を、読み込んでいない宣言が上書きする可能性があるということである。そのため、そのような事態を発生させる可能性があるパラメタ実体参照が出現した後のこれらの宣言を処理してはならないのである。

 しかし、これらの宣言を処理しなければならない例外規定が付いている。つまり、非依存文書宣言が「standalone="yes"」のときは処理しなければならないのである。なぜ、この場合のみ実行すべき内容が異なるのかといえば、非依存文書宣言によって非依存文書であると宣言するということは、妥当性を検証しないプロセッサが処理しないかもしれない宣言に依存する部分はない、ということを宣言することとイコールだからである。それ故に、「standalone="yes"」と明記されたXML文書を処理する場合、処理結果に影響する宣言の上書きは存在しないと見なすことができ、たとえ読み込んでいないパラメタ実体への参照があったとしても、それは読み飛ばしても安全である。しかし、ここでは、単に安全であるというだけでなく、処理しなければならない(MUST)と必須の要求としている。これにより、処理されるかどうか分からないあやふやな状態が1つ解消されていて、利用者からは使いやすくなっているといえる。

 さて、そろそろお待ちかねのトリックの解説に入ろう。「Process Declarations(処理宣言)」として定義された用語は、実はそのとおりの文字列では出現していない。しかし、途中に単語を挟むことで、それと同じものを示す用語が出現している。例えば、上記段落中の「process all the declarations(すべての宣言を処理)」であるとか、「process these declarations(宣言を処理)」といった用語が、いずれも定義された「Process Declarations」という用語の使用例であると思う。蓋を開けてみれば、何ということはない話だが、文字列検索機能に頼っていると気付きにくい用法だろう。

 次は、妥当性を検証しないプロセッサで、妥当でない文書を処理する場合の規定である。

Note that when processing invalid documents with a non-validating processor the application may not be presented with consistent information. For example, several requirements for uniqueness within the document may not be met, including more than one element with the same id, duplicate declarations of elements or notations with the same name, etc. In these cases the behavior of the parser with respect to reporting such information to the application is undefined.

妥当性を検証しないプロセサで、妥当でない文書を処理するとき、応用プログラムは一貫性のある情報を受け取るとは限らないことに注意されたい。例えば、文書中において一意であるといういくつかの要件は、満足されるとは限らず、それには1つ以上の要素が同じidを持つこと、同じ名前の要素型宣言または記法宣言が重複することなどがある。これらの場合、応用プログラムにこのような情報を報告する点に関するパーサの振る舞いは、定義しない。

 冒頭の文章では、妥当でない文書は、当然ながら整形式の文書に要求される制約は満たしているが、それ以外の制約を満たしている保証がないと述べている。次の文章で、その具体例について述べている。例えば、ある値のID型の属性値は1つの文書中に1回しか出現してはならないという制約があるが、妥当性を検証しないプロセッサではそれはチェックされることはないということである。つまり、本来一意であることを期待するID値であるにもかかわらず、同じ値を複数含む文書を受け付けてしまうということである。次の文章は、その際の振る舞いについて書かれている。つまり、そのような事態が発生した場合にどのように対処するのか、単に無視するのか、それとも報告するのかは、XML 1.0勧告では定義されない。それは実装依存ということになる。

 以上で、「5.1 Validating and Non-Validating Processors(5.1 妥当性を検証するプロセッサおよび検証しないプロセッサ)」をすべて読み終わった。「5 Conformance(5 適合性)」で残るのは、「5.2 Using XML Processors(5.2 XMLプロセッサの使用)」だけである。(次ページへ続く)

2/3

 Index
やさしく読む「XML 1.0勧告」 第33回
XML勧告への適合性を示すConformance
  Page 1
・XML 1.0への適合条件を示す「Conformance」
・適合性(Conformance)の意義
Page 2
・妥当性を検証するプロセッサおよび検証しないプロセッサ
  Page 3
・XMLプロセッサの使用


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


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

注目のテーマ

HTML5+UX 記事ランキング

本日月間