XMLマスターポイントレッスン ~ ベーシック編 ~
第4回 DTDによるXML文書の妥当性検証
インフォテリア認定教育センター 森田浩美 MORITA, Hiromi
前回は、XML文書の階層構造や要素名などを定義するためのスキーマをスキーマ定義言語「DTD」で記述し、その定義に沿ったXML文書の作成方法を解説しました。XML文書としての記述法や構造には決まりがあり、その決まりに従って作成されたXML文書は「整形式XML文書」や「妥当なXML文書」と呼ばれ、必ずどちらかである必要があります。今回は、この2つの文書形式について説明します。ベーシックV2試験のセクション2「XML文書の作成」セクション3「DTD」を攻略する上で必須知識となりますので、しっかりと学習しておきましょう。
2つの種類のXML文書
本連載の第1回で、XMLの特徴として自由に要素名や階層構造を定義できること、人間もコンピュータにとっても理解しやすいデータ形式であることを説明しました。また、XML文書はさまざまな形式のデータも表現でき、個人データや企業システムのフォーマットなど、その活躍/活用の場が無限にあると言って良いことも説明しました。
このような特徴を持つXMLですが、前回の解説で、XML文書の作成において個人で扱うデータをXMLで記述する場合と企業システムのフォーマットとしてXMLを使用する場合とでは、考え方が少し異なるということを覚えているでしょうか。
個人で扱うデータの場合は、ほかの人やシステムで利用することを考える必要がなく、自由に要素名、階層構造を定義できます。そのため、基本的にはXMLインスタンスのみ記述すればXML文書を作成できます。
しかし、XMLを企業システムのデータフォーマットとして使用する場合は、ほかの人やシステムが利用することも考える必要があるため、スキーマ定義言語(DTD:Document Type Definition)でスキーマ文書を作成し、そのスキーマ文書に従ってXML文書を作成することで、誰が記述しても同じ構造のXML文書が作成できるようにしなくてはなりません。これにより、システム連携における自動化と処理効率の向上が実現できるのです。
XML 1.0の仕様では、前者を「整形式XML文書(Well-formed XML document)」、後者を「妥当なXML文書(Valid XML document)」と呼びます。
整形式XML文書(Well-formed XML document)
「整形式XML文書」は、XML 1.0の仕様に記述されている文法に従って作成された文書です。主に以下の規則を守って記述された文書です。
[1] ルート要素は1つである
●正しい例(整形式XML文書)
<person>
<name>yamada</name>
</person>
●誤っている例
<person></person>
<name>yamada</name>
[2] 要素名や属性名は命名規則に従っている
●正しい例(整形式XML文書)
<name>yamada</name>
●誤っている例
<123>yamada</123>
[3] 入れ子構造が正しく記述されている
●正しい例(整形式XML文書)
<person>
<name>yamada</name>
<age>10</age>
</person>
●誤っている例
<person>
<name>yamada<age>10</name></age>
</person>
[4] 開始タグ、終了タグの整合性が取れている
●正しい例(整形式XML文書)
<name>yamada</name>
●誤っている例
<name>yamada</NAME>
整形式XML文書は、XML宣言と文書型宣言は省略できますが、XMLインスタンスは必須です。XML文書と呼ばれる文書は必ず整形式XML文書でなければなりません。みなさんがXML文書を作成したつもりでも、そのXML文書に文法上の誤りがある場合、あえて分類するのであれば、テキスト文書となります。
妥当なXML文書(Valid XML document)
整形式XML文書であり、かつDTDなどのスキーマ定義言語で定義されている文書構造(要素名や階層構造)に従って記述されたXML文書を「妥当なXML文書」と呼びます。DTDで記述したXML文書では、XML宣言は省略できますが、文書型宣言とXMLインスタンスは必須です。
DTDの要素型宣言と実体宣言については前回説明しました。要素型宣言では、XML文書に出現する要素名と、その要素の内容(内容モデル)の出現要素名と出現順序、出現回数を定義するのでしたね。整形式文書と妥当なXML文書の違いを図1に示します。また、整形式XML文書と妥当なXML文書の関係は図2のとおりです。すべてのXML文書は必ず整形式XML文書であるということから、妥当なXML文書も整形式XML文書の一部です。
文書型を判断する「XMLパーサー」
みなさんが作成したXML文書や世の中に存在するXML文書は、整形式XML文書か妥当なXML文書と判断されることを説明しました。では、誰(何)が「このファイルは整形式XML文書です」「このファイルは妥当なXML文書です」と判断するのでしょうか。いくつか、次に示してみました。
(1)ファイルの拡張子
(2)XMLインスタンス
(3)人間
(4)XMLパーサー
みなさんはどれが正解だと思いますか。1つずつ見ていきましょう。
まず、(1)ファイルの拡張子ですが、図1の例でも分かるように、すべて拡張子は.xmlです。XML文書の拡張子には.xmlを指定するのが一般的ですが、XML 1.0の仕様ではXML文書の拡張子には制限がありません。したがって、拡張子で整形式XML文書か妥当なXML文書かは指定できません。すなわち、拡張子では整形式XML文書と妥当なXML文書は判断できません。
(2)のXMLインスタンスはどうでしょうか。XMLインスタンスは、実際のデータを記述する場所です。XMLは自由に要素名を定義できますので、整形式XML文書か妥当なXML文書かを指定する特別な要素はありません。
(3)の人間は、人間がXML文書に記述された内容をチェックし、判断することは不可能ではありません。しかし、毎回ファイルを開いて判断するのは大変です。整形式XML文書の規則を熟知し、妥当なXML文書のスキーマ定義とXML文書を見て判断しますので、小さいXML文書ならともかく、大きなXML文書の場合は判断するのに相当時間を要します。したがって、人間がファイルを開いて判断するということは現実的ではありません。
そうすると、正解は(4)のXMLパーサーです。XMLパーサーは、整形式XML文書か妥当なXML文書かをチェックし、アプリケーションが理解しやすい形に変換するソフトウェアです。XMLパーサーは必ず整形式XML文書かの判断を行ないます。妥当なXML文書かを判断するかどうかは、XMLパーサーに依存します。ほとんどのXMLパーサーは両方を判断する機能を提供していますが、整形式XML文書のみを判断するパーサーを「非検証XMLパーサー」、妥当なXML文書を判断するパーサーを「検証パーサー」と呼びます。人間が判断するより、はるかに高速かつ正確に判断できます。
XMLパーサーのチェック手順
では、XMLパーサーはどのようにチェックを行なうのでしょうか?
XMLパーサーは、最初に読み込んだファイルが整形式XML文書であるかをチェックします。この時点で、XML 1.0の文法に従っていない記述がある場合は致命的エラー(fatal error)を通知します。先ほど説明したとおり、妥当なXML文書である条件の1つに「整形式XML文書である」という項目がありますので、整形式XML文書のチェック時点で誤りがある場合、妥当なXML文書かをチェックをする必要がないのです。読み込んだファイルがXMLインスタンスのみの場合は、ここでチェックは終了します。
その後、スキーマ文書で特定の要素名や階層構造が定義されている場合は妥当性のチェックを行なうかどうかを判断します。妥当性のチェックを行なわない場合には整形式XML文書となり、妥当性のチェックを行なう場合は文書構造に合致しているかをチェックします。もし、妥当なXML文書に違反している場合はエラー(error)を通知します(図3)。
このXML文書はどっち?
では、実際にいくつかのXML文書を「テキスト文書」「整形式XML文書」「妥当なXML文書」に分類してみましょう。サンプルのXML文書(LIST1~5)を用意しましたので、考えてみてください。
LIST1:サンプルXML文書[1]
●samp1.xml
<社員>
<氏名NO>1234567</氏名NO>
<氏名>yamada</氏名>
</社員>
LIST2:サンプルXML文書[2]
●samp2.dtd
<!ELEMENT 社員(氏名NO,氏名)>
<!ELEMENT 氏名NO (#PCDATA)>
<!ELEMENT 氏名(#PCDATA)>
●samp2.xml
<!DOCTYPE 社員SYSTEM "samp2.dtd">
<社員>
<氏名NO>1234567
<氏名>yamada</氏名>
</社員>
LIST3:サンプルXML文書[3]
●samp3.dtd
<!ELEMENT 社員(氏名NO,氏名)>
<!ELEMENT 氏名NO (#PCDATA)>
<!ELEMENT 氏名(#PCDATA)>
●samp3.xml
<!DOCTYPE 社員SYSTEM "samp3.dtd">
<社員>
<氏名NO>1234567</氏名NO>
<氏名>yamada</氏名>
</社員>
LIST4:サンプルXML文書[4]
●samp4.dtd
<!ENTITY TV "televesion">
●samp4.xml
<!DOCTYPE 製品SYSTEM "samp4.dtd">
<製品>&TV;</製品>
LIST5:サンプルXML文書[5]
● samp5.dtd
<!ENTITY TV "<名前>televesion">
●samp5.xml
<!DOCTYPE 製品SYSTEM "samp5.dtd">
<製品>&TV;</製品>
まず、LIST1のXML文書はどうでしょうか。ルート要素が1つ、入れ子構造も適切、要素名も命名規則に従っている、とXML文書の条件を満たしています。そして、このファイルにはスキーマ定義が記述されていませんので整形式XML文書です。
次に、LIST2のXML文書には、スキーマ文書とXML 文書が記述されています。「この2つが記述されているということは、妥当なXML文書の可能性が高いな」と判断した人はいませんか?焦りは禁物ですよ。先ほど説明したとおり、まずは整形式XML文書のチェックから行ないます。LIST2のXML文書には、氏名NO要素の終了タグがないため、XML文法に従っていません。よって、このXML文書は整形式XML文書でも妥当なXML文書でもなく、ただのテキスト文書となります。
続いて、LIST3のXML文書はどうでしょうか。このXML文書はXMLの文法に従っており、さらにDTDで定義されている文書構造にも従っているため、妥当なXML文書です。
LIST4のXML文書には、XML文書とスキーマ文書があります。まず、XML文書を見るとXML文法に従っているため、整形式XML文書であると分かります。次に、スキーマ文書がありますので、文書構造が合致していれば妥当なXML文書になります。スキーマ文書には実体宣言(今回は置換文字列)のみ定義されています。さて、このXML文書は整形式XML文書でしょうか、それとも妥当なXML文書でしょうか。
妥当なXML文書になるための条件
妥当なXML文書に分類される条件をもう1度思い出してみましょう。「整形式XML文書であり、かつスキーマ文書で定義されている文書構造に合致している文書」です。実体宣言は文書構造にあたるのでしょうか。
実体宣言とは、置換文字列(内部実体)を定義したり、外部ファイル(外部実体)を取り込むことができる宣言であり、実体と実体名を実体宣言で定義します。XML文書に出現する要素名や階層構造(すなわち文書構造)を定義する宣言ではありません。実はLIST4のXML文書は整形式XML文書なのです。したがって「整形式XML文書であり、かつDTDなどによるスキーマ文書に従った文書」とは言わず、「整形式XML文書であり、かつスキーマ文書で定義されている文書構造に合致している文書」と記述していたのです。
なお、置換文字列や外部ファイルの実体も整形式XML文書の文法に従う必要があります。すなわち、LIST5のXML文書はエラーとなり、テキスト文書です。
今月の確認問題
整形式XML文書と妥当なXML文書の違いは、しっかり理解できたでしょうか?ここで、今回解説した内容が理解できたかどうか、確認問題で試してみましょう。
問題1
XMLパーサーについて正しい記述を2つ選択してください。
- Webブラウザには必ずXMLパーサーが組み込まれている
- 非検証XMLパーサーでXML文書を検証する場合、DTDを記述してはいけない
- 検証XMLパーサーで妥当なXML文書を検証する場合、必ずスキーマ定義言語による文書構造定義が必要である
- DTDを用いて妥当なXML文書を検証する場合は、必ずXML文書に文書型宣言(<!DOCTYPE・・・>)が必要である
解説
本連載で使用したInternet ExplorerにはXMLパーサーが組み込まれていますが、すべてのWebブラウザに組み込まれているとは限りません。したがってAは誤りです。
非検証XMLパーサーでは、整形式XML文書かのチェックを行ないます。ただし、DTDで実体宣言(内部実体:置換文字列)が記述されている場合はDTDが展開されますので記述しても構いません。また、要素型宣言(文書構造定義)が記述されていても検証を行なわないだけなので、記述されていても構いません。したがってBは誤りです。
検証XMLパーサーで妥当なXML文書を検証する場合は、スキーマ定義言語による文書構造の定義が必要となります。したがってCは正解です。
DTDを用いて妥当なXML文書を検証する場合には、必ず文書型宣言(<!DOCTYPE・・・>)が必要です。したがってDも正解です。
問題2
次のXML文書の中で、整形式XML文書ではあるが、妥当ではないXML文書を選択してください。
- <社員>
- <社員>yamada</社員>
- DTD(mon_c.dtd)
<!ELEMENT 社員(#PCDATA)>
XML
<!DOCTYPE 社員SYSTEM "mon_c.dtd">
<社員>yamada</社員> - DTD(mon_d.dtd)
<!ELEMENT 社員(#PCDATA)>
XML
<!DOCTYPE 社員SYSTEM "mon_d.dtd">
<名前>yamada</名前>
解説
妥当なXML文書は、整形式XML文書であり、かつ文書構造に従った文書です。また、整形式XML文書はXML 1.0の文法に従った文書です。
Aは、社員要素の終了タグがありません。したがって、整形式XML文書ではないためテキスト文書です。Aは誤りです。Bは、社員要素が正しく記述されており、文書構造の定義が記述されていないため整形式XML文書になります。したがってBは正解です。
Cは、整形式XML文書であり、かつ文書構造定義にしたがっているため妥当なXML文書となります。したがってCは誤りです。Dは、整形式XML文書ですが、文書構造定義にしたがっていない(文書構造定義では、社員要素が1回出現であるのに対し、XMLインスタンスでは名前要素が出現している)ため、妥当ではないXML文書となります。したがってDは正解です。
問題3
妥当なXML文書と整形式XML文書について正しい説明文を選択してください。
- 整形式でないXML文書は必ず妥当ではない
- 整形式XML文書においてDTDを使用することはない
- 妥当なXML文書は必ず整形式である
- 妥当でないXML文書は絶対に整形式ではない
解説
妥当なXML文書は、整形式XML文書であり、かつ文書構造に従った文書です。したがって、整形式XML文書でないXML文書は、妥当なXML文書のチェックを行ないません。よってAは正しい記述です。
XML文書に実体宣言が記述されていた場合、内部実体(置換文字列)はXMLパーサーが展開し、外部実体(外部ファイル取り込み)の展開はXMLパーサーに依存します。したがって、整形式XML文書でもDTDを記述しても正しい整形式XML文書と判断するため、Bは誤りです。
妥当なXML文書は、整形式XML文書の一部です。整形式XML文書のチェックの後に、妥当なXML文書のチェックを行ないます。妥当なXML文書と判断された場合は、必ず整形式XML文書です。したがってCは正しい記述です。また、妥当でないXML文書と判断された場合でも、整形式XML文書である可能性はあります。したがって、Dは誤りです。
* * *
今回は、XML文書は記述形式によりテキスト文書、整形式XML文書、妥当なXML文書に分類されることを理解できたでしょうか。XML文書を用いる際に、整形式XML文書と妥当なXML文書という2つのキーワードが飛び交うことが多いと思います。ぜひ、この違いを覚えておきましょう。
次回からは、スキーマ定義言語の1つである「XML Schema」について説明します。
森田浩美(もりたひろみ)
株式会社日立システムアンドサービス人財教育部に勤務。インフォテリア認定トレーナーとしてXMLの講師や社内で講義を担当。今回で本連載の担当が終わりホッと一安心……。またいつかお会いする日が来ることを楽しみにしています。
<掲載> P.207-211 DB Magazine 2006 May