第12回 XMLにおける空白、行末、言語識別

XML 1.0は、1998年にW3Cから勧告として公開された。当然中身は英語で、しかもEBNFと呼ばれる式によって重要な部分が記述してある。この連載では、XML 1.0を深く理解するために、そのXML 1.0勧告の最新版「Extensible Markup Language (XML) 1.0 (Second Edition)」をだれでも分かるように、やさしく読み解きながら解説していくことを目指している。(編集局)

川俣 晶
株式会社ピーデー
2003/7/25



空白と言語識別を一気に読む
今回の主な内容
空白と言語識別を一気に読む
空白文字の取り扱い
妥当性を検証するXMLプロセッサがすべきこと
xml:space属性の役割
xml:space属性の取り得る値
環境ごとに異なる行末の取り扱い
行末は#xAとなる
言語識別
言語の識別と、国や地域の識別

  前回の「XMLの外部参照と非依存文書宣言」では、XML 1.0勧告の中で、XML宣言や文書型宣言を扱っている部分である「2.8 Prolog and Document Type Declaration」(2.8 前書き及び文書型宣言)と、XML宣言に含まれる非依存文書宣言に関する説明「2.9 Standalone Document Declaration」(2.9 非依存文書宣言)を読み切った。

 これら2つは多少関係がある話題だったが、今回解説する内容は、それらとは直接的にはつながりがない。今回扱うのは、以下の3つである。まず、「2.10 White Space Handling」(2.10 空白の取扱い)は、空白文字の扱いに関する規定を記述している部分である。空白文字の定義はすでに「2.3 Common Syntactic Constructs」(2.3 共通の構文構成子)で読んだ。今回は、空白文字の扱いについての解説だ。

 次は、「2.11 End-of-Line Handling」(2.11 行末の取扱い)である。行末は制御文字を使って示すことになるが、環境によって異なるコードが使用されており、何らかの規定を設けなければ異種環境間での相互運用性が維持できない性質のものである。

 最後は、「2.12 Language Identification」(2.12 言語識別)である。これは、XML文書のある部分に記述された文字列が、どのような言語(日本語であるとか英語であるとか)で記述されているかを示すために使用される。

 今回で、「2 Documents」のセクションも終わりである。あと一息なので、頑張って乗り切ろう。

編集注:この連載では、XML 1.0勧告であるW3Cの「Extensible Markup Language (XML) 1.0 (Second Edition)」(英語)を参照し、その日本語訳として、日本工業規格 JIS X 4159:2002(リンク先は該当規格の原案ですが、最終版とほぼ同等の内容です)を参照しています。本文中のピンクの地の部分は、XML 1.0勧告の原文を示しています。

空白文字の取り扱い

 空白文字の定義は、すでに、「2.3 Common Syntactic Constructs」(2.3 共通の構文構成子)に記述されている。“[3] S ::= (#x20 | #x9 | #xD | #xA)+”というのが、EBNF的な空白文字の定義である(EBNFの詳細については、第2回「XML勧告読解に必須のEBNF」を参照)。ここで解説するのは空白文字の定義ではなく、空白文字の扱われ方である。それを意図的に指定するための属性が1つ定義されている。

 では本文を読み始めよう。

In editing XML documents, it is often convenient to use "white space" (spaces, tabs, and blank lines) to set apart the markup for greater readability. Such white space is typically not intended for inclusion in the delivered version of the document. On the other hand, "significant" white space that should be preserved in the delivered version is common, for example in poetry and source code.

XML文書を編集するときは、マーク付けを目立たせ読みやすくするために“空白”(スペース、タブおよび空白行)を使うと便利なことが多い。これらの空白は、配布する版の文書の一部に含めることを普通は意図していない。一方、“意味のある”空白もあり、配布する版に保持されなければならないものも多い。例えば、詩およびソースコードにおける空白がこれに当たる。

 まず、読みやすさのために挿入される空白文字は、文書の意味のある一部ではないことを示している。例えば、要素の内容を字下げして記述するXML文書は多いが、字下げに使われた空白文字は、文書のデータの一部ではない、ということである。しかし、それだけが空白文字の使い方ではなく、意味のある空白、例えば詩やソースコードにおける空白がこれに当たる、と例も示している。

 poetry(詩)で使われる空白が保持されねばならないというのは、字下げに使われる空白文字も詩を構成する芸術的な表現の一部と考えられるためだろう。表現のために作者が入れた空白文字は重要な意味があり、決して取り除いてはならないものである。

 ソースコードにおける空白にも同じような意図がある。ソースコードの意図を分かりやすく表現するために挿入された空白文字は意味があり、取り除いてはいけない。世の中には、字下げによってブロック構造を表現するプログラム言語(TransputerというCPUのためのプログラム言語、Occamがそうだったような記憶がある)もあり、そのような場合には空白文字を変更することは致命的なプログラムの破壊につながる。

 以上は、これから始まる規定の前振りとなる説明文である。

An XML processor must always pass all characters in a document that are not markup through to the application. A validating XML processor must also inform the application which of these characters constitute white space appearing in element content.

XMLプロセサは、文書内のマーク付け以外のすべての文字を変更せずにそのまま応用プログラムに渡さなければならない(must)。妥当性を検証するXMLプロセサは、これらの文字の中でどの文字が要素内容に出現する空白を構成するかを応用プログラム側に伝えなければならない(must)。

 いよいよ、空白文字の扱いに関する規定に入っていく。ここでは“空白文字”ではなく“文字”と記述されているが、当然これには空白文字が含まれる。「空白文字であろうと、(マーク付け以外の)すべての文字は変更せずに応用プログラムに渡されなければならない」。マーク付け以外の、というのは、逆にいえば、マーク付けの内部の空白文字は渡さなくてもよいということを示す。例えば、

<element attribute="value">

という開始タグが記述されているとき、elementとattributeの間の空白文字は、応用プログラムに渡されない。そこに書かれた空白文字が空白なのか改行なのかタブなのか、あるいは何個の空白文字が入っていたか、応用プログラムが知ることはない。

妥当性を検証するXMLプロセッサがすべきこと

 次は、妥当性を検証するXMLプロセッサに関する規定である。「妥当性を検証するXMLプロセサは、これらの文字の中でどの文字が要素内容に出現する空白を構成するかを応用プログラム側に伝えなければならない(must)」としている。ここは少し分かりにくいところである。すべての空白文字を応用プログラムに渡さねばならない、というのは必須要件である。ともかくそれは渡されるのである。それに加えて、妥当性を検証するXMLプロセッサを使う場合、どの文字が「要素内容に出現する空白」であるかを応用プログラムに伝えなければならない。

 しかし、「要素内容に出現する空白」とは何だろうか? 要素内容という言葉の定義は「3.2.1 Element Content」(3.2.1 要素内容)に出てくることになり、まだ先である。しかし分からないままでは読み通せないので、簡単に説明して先に進むことにしよう。要素内容の定義は、「ある型の要素が必ず子要素だけを含み(文字データを含まない)、それらの間には空白(非終端記号Sにマッチする文字)だけしか現れないとき、その要素型は要素内容を持つという」ということである。つまり、要素内容には、文字データは含まれず、要素だけを子に持つ。ただ、空白文字だけは含むことを許されているわけである。別のいい方をすれば、要素内容であるということは混合内容ではない、ということだ。混合内容は、文字データが子として出現することを許すものである。

 これをまとめると、「要素内容に出現する空白」とは、文字データが出現することがDTDによって禁止されている要素の内容に出現する空白文字」といえる。そして、どの文字がこの条件に合致した文字であるかを、XMLプロセッサは応用プログラムに伝えなければならない、というのである。当然のことながら、混合内容に出現した空白と、要素内容に出現する空白は違うものだと認識して、それを伝える必要が発生する。応用プログラムから見ると、混合内容に出現した空白は意味のあるものとして受け付けるべきだが、要素内容に出現した空白は読み飛ばすべきものといえる。

xml:space属性の役割

 さて、次の段落からは、別の話題に変わる。今度は、xml:space属性に関する話題である。

A special attribute named xml:space may be attached to an element to signal an intention that in that element, white space should be preserved by applications. In valid documents, this attribute, like any other, must be declared if it is used. When declared, it must be given as an enumerated type whose values are one or both of "default" and "preserve". For example:

xml:spaceという特別な属性を要素に加えることによって、応用プログラムはこの要素の中の空白を保存することが望ましい、という意図を示してもよい。妥当な文書では、この属性を使用する場合はほかの属性と同じように宣言しなければならない。宣言するときは、取り得る値を“default”“preserve”のいずれか、または両方に限る列挙型でなければならない。

 これもまた分かりにくい文章である。前の文章で既に、「文書内のマーク付け以外のすべての文字を、変更せずにそのまま渡さなければならない」と力強く断言したばかりである。それにも関わらず、ここで「空白を保存することが望ましい、という意図」などという言葉が出てくるのはなぜだろうか。

 ここで注意すべきことは、「意図(intention)」という表現である。これは、XMLプロセッサや応用プログラムの動作に対する規定を示している言葉ではない。あくまで、XML文書の作成者の考えたことを示す手段、と理解すべきだろう。結局のところ、xml:space属性の有無によって、XMLプロセッサの動作が変わることはない、ということになるのである。

 続いての文章は、xml:space属性を使う場合は、DTDの属性リスト宣言にこの属性も書いておけ、という意味である。xml:spaceという名前は一見名前空間を使用しているように見える。xmlが接頭辞ということである。しかし、名前空間を併用しないXML1.0で利用する場合は、“xml:space”がひと続きの、1つの属性名であることに注意が必要である。名前空間使用時には、xmlという接頭辞が宣言しなくても、暗黙的に名前空間URIのhttp://www.w3.org/XML/1998/namespaceに関連付けられるため、この属性はこの名前空間URIに属するspaceという名前の属性ということになる。しかし、この名前空間URIに別の接頭辞を与えてspace属性を記述することはできない。

 そして、宣言するときは、取り得る値を“default”か“preserve”のいずれか、または両方に限る列挙型でなければならない。ここで述べられた2つの文字列だけが正しい値として指定可能ということである。

 その次は、この属性を属性リスト宣言で記述した例である。

<!ATTLIST poem  xml:space (default|preserve) 'preserve'>

<!-- -->
<!ATTLIST pre xml:space (preserve) #FIXED 'preserve'>

 最初の例は、poem要素に付加されるxml:space属性について記述している。取り得る値は“default”か“preserve”のどちらか一方であり、省略時のデフォルト値はpreserveであることを示している。2番目の例は、pre要素に付加されるxml:space属性について記述しているが、こちらは選択の余地がなく、preserveのみが指定されている。この例では、defaultを記述することは間違いとなる。

xml:space属性の取り得る値

 さて、次はdefaultとpreserveという値の持つ意味についての説明である。

The value "default" signals that applications' default white-space processing modes are acceptable for this element; the value "preserve" indicates the intent that applications preserve all the white space. This declared intent is considered to apply to all elements within the content of the element where it is specified, unless overriden with another instance of the xml:space attribute.

値“default”は、応用プログラムのデフォルトの空白処理モードがその要素に適用できることを意味する。値“preserve”は、応用プログラムがすべての空白を保存することを意味する。この宣言の意図は、xml:space属性の別の指定で上書きしない限り、要素の内容に現れるすべての要素に適用すると解釈する。

 まず、「応用プログラムのデフォルトの空白処理モードがその要素に適用できる」という“default”について。ここで重要なことは、XMLプロセッサの空白処理モードではなく、もし応用プログラムが独自の空白文字処理機能を持っているなら、それを使うということである。例えば、応用プログラムが空白文字を増減してきれいにページに収まるように書式整形する機能があるなら、それを使ってよい。

 次に、「応用プログラムがすべての空白を保存する」という“preserve”は、応用プログラムが空白文字を勝手に変えてはならない。応用プログラムが、空白文字を増減してきれいにページに収まるように書式整形する機能があるとしても、それを使ってはならないということだ。

 余談だが、少し前に記述された例の要素名がpoemとpreであるというのは、何となくこの属性の使い道を暗示させる。poemつまり詩は、空白文字を意味のあるものとして保存する必要があるかもしれない。つまり、どちらの空白処理モードを使うかを明示的に属性で示す価値がある。一方、preの方はHTMLのpre要素を連想させる。HTMLのpre要素は、記述された空白文字をそのままWebブラウザ上に表示するタグだ。そのため、常に空白文字はそのまま扱われる必要があり、値を自由に指定する選択の余地を与える意味はないといえる。

 xml:space属性による指定は、子孫要素にも伝播する。そして、子孫要素側でxml:space属性を記述することで、その要素とその子孫には違う指定を適用することができる、ことも説明されている。

 次は、xml:space属性とルート要素との関連性についての規定である。ルート要素は親要素が存在しないため、上位の指定がないという点で特殊である。そのため、特に規定が必要とされるわけである。

The root element of any document is considered to have signaled no intentions as regards application space handling, unless it provides a value for this attribute or the attribute is declared with a default value.

文書のルート要素については、この属性の値を指定するか、またはこの属性のデフォルト値が宣言されている場合を除いては、応用プログラムによる空白の取扱いについていかなる意図も示さない、と解釈する。

 ちょっと長いので分解して読んでみよう。まず、「この属性の値を指定するか、またはこの属性のデフォルト値が宣言されている場合」というのは、ルート要素にxml:space属性に関する情報が指定されている場合、ということを意味する。属性の値を指定する方法は、XML文書上に明示する方法と、属性のデフォルト値をDTDに書き込む方法の2つがあるが、そのような指定がなされていない場合について話が続く。指定がなされていない場合、「いかなる意図も示さない」。つまり、defaultでもpreserveでもない状態になっている、ということである。そのことから考えると、実は、空白の扱いは、以下の3つのケースがあることになる。

  • 示されていない
  • default
  • preserve

 preserve以外はどういう動作をさせれば適切なのか分かりにくい。しかし、すでに見たように、XMLプロセッサの動作としては、この指定に影響を受けることはない。応用プログラム側が、この指定の違いによって動作を変えたい場合だけ、この違いを意識するとよいだろう。その際、「示されていない」というあいまいな状態が好ましくなければ、DTDによってルート要素にxml:space属性の記述を必須としたり、デフォルト値を持つ属性として追加しておくことも可能だろう。もちろん、DTD以外のスキーマ言語で指定しておいてもよい。

環境ごとに異なる行末の取り扱い

 行末を示すコードは、環境によって違う。例えば、UNIX系OSの世界では改行コード(#xA)を使うが、Macintoshの世界では復帰コード(#xD)を使う。Windowsの世界では復帰と改行(#xD;#xA)という2文字のシーケンスで示す。このような違いを無視して、XML文書における行末を示すコードを無理やり統一しようとすれば、非常に大きな使い勝手の悪さを招く。かといって、ここに挙げたすべてを有効な行末として受け入れるように応用プログラムを記述するのも面倒な作業である。

 以下に、そのあたりに関する規定が記述されている。

XML parsed entities are often stored in computer files which, for editing convenience, are organized into lines. These lines are typically separated by some combination of the characters carriage-return (#xD) and line-feed (#xA).

XMLの解析対象実体は、通常コンピュータのファイル内に保存され、編集の便宜のために複数の行に分けることが多い。これらの行は、普通は復帰(#xD)コードおよび改行(#xA)コードの何らかの組み合わせによって分けられる。

 解析対象実体というのは、XMLの構文で記述された実体であり、XML文書などを指す。これを複数の行に分けて記述するのは、よく行われる普通のことである。

 ここで述べられていることは、すでに述べたOS環境などによる行末を示すコードの相違の説明である。とはいえ、ここには1つだけ問題がある。「普通は」という限定が付いているが、これがどこからどこまでを含むのかは明示されていない。実際、メインフレームなどでは異なる改行コードが使用されていて、「復帰(#xD)コードおよび改行(#xA)コードの何らかの組み合わせ」では収まらない事例があり、これがXML 1.0から1.1への改版の1つの原動力となっている(XML 1.1は、2003年7月現在、策定中)。とはいえ、XML 1.0勧告の世界では、行末はここで示された範囲内で使うのが基本である。

 なお、ISO 10646(Unicode)の#x80〜#x9fの範囲は制御文字であり、これはXML 1.0勧告で使用できる文字の範囲に含まれる(EBNFの[2] Charの定義を参照)。メインフレームの改行コードに当たる#x85はこの範囲に含まれるので、XML文書に書き込んでよいように思えるが、たとえ書き込んだとしても、XML 1.0勧告準拠のXMLプロセッサはこれを行末として処理することはない。

行末は#xAとなる

 次は、応用プログラムに渡す行末情報についての規定である。

To simplify the tasks of applications, the characters passed to an application by the XML processor must be as if the XML processor normalized all line breaks in external parsed entities (including the document entity) on input, before parsing, by translating both the two-character sequence #xD #xA and any #xD that is not followed by #xA to a single #xA character.

応用プログラムの仕事を簡単にするため、XMLプロセサは次の処理をした場合と同一の文字を、応用プログラムに渡さなければならない。入力された(文書実体を含む)外部解析対象実体の中のすべての行末(連続する2文字#xD #xA、および#xAを後ろに伴わない#xD)を、解析を行う前にXMLプロセサが単一の#xAに変換することによって正規化する処理とする。

 「XXした場合と同一の文字を」という表現が少し奇異に見える。何かの処理を強制したいなら、「XXせよ」と書くのが最も単純だが、そのような表現を行っていない。その理由は、手段を強制しないことにある。応用プログラムに渡る結果が同じなら、さまざまに処理方法を工夫して、より利便性の高いXMLプロセッサを開発すべきなのである。そのためには、ここで記述されたのとは異なる手順で、同じ結果を実現したいかもしれない。そのような実装もOKであるという意図を示すために、「XXした場合と同一の文字を」という表現になっているのである。

 では具体的にどんな処理なのか。説明されているのは、文書実体、外部解析対象実体に対して、解析を行う前に以下の処理をせよ、ということである。

  • 連続する2文字#xD #xA→#xA
  • #xAを後ろに伴わない#xD→#xA

 これにより、すべての行末は#xAで表現されるようになる。その結果、その後のプログラムの処理が簡単になる。ある文字が#xAであるか否か、というシンプルな判定で、行末かどうかを判定できるようになる。

 このことから分かるとおり、XMLでは、環境ごとの行末の相違を明示的に意識して扱うことはできない。例えば、行末が#xAである場合と、#xDである場合で処理を分ける応用プログラムを作成する、といったことはできない。

言語識別

 ここでは、言語識別のために付加することができるxml:lang属性について記述されている。ある文章が日本語で書かれているか、英語で書かれているかで重要な違いが生じる場合がある。例えば、日本語の文章に英語の単語が挿入されている場合に、その単語が日本語の規則に沿ってレイアウトされるか、英語の規則に沿ってレイアウトされるか、その相違によって、ページに配置される文字の位置が変わる場合があり得る。このような問題は広く一般的に出現し得るので、XMLのようなごく基本的なマーク付け言語の仕様の中で定義を与える価値がある。

 では本文を読んでいこう。

In document processing, it is often useful to identify the natural or formal language in which the content is written. A special attribute named xml:lang may be inserted in documents to specify the language used in the contents and attribute values of any element in an XML document. In valid documents, this attribute, like any other, must be declared if it is used. The values of the attribute are language identifiers as defined by [IETF RFC 1766], Tags for the Identification of Languages, or its successor on the IETF Standards Track.

文書処理においては、その文書の中身がどんな自然言語または形式言語で書かれているかを明示すると、役に立つことが多い。XML文書内の要素の持つ内容または属性値において使用する言語を指定するために、xml:langという名前の特別な属性を文書内に挿入してもよい。妥当な文書においてこの属性を使用する場合は、ほかの属性と同様に宣言しなくてはならない。この属性の値は、言語識別のためのタグ [IETF RFC 1766]、またはIETF標準化トラックの後継規定で定義される言語識別コードとする。

 文書処理とは、もちろんコンピュータで電子的な文書を処理することをいう。ここでいう文書は、必ずしもXMLで扱うすべての文書とは一致しないものである。自然言語というのは、日本語や英語など、だれかが定義することなく自然発生的に人間が使っている言語である。形式言語というのは、筆者の知識の範囲を外れるので辞書を引いたところ、「生成文法が対象とする、数学的な文法規則により生成される抽象的言語」と記述されていた。そういえば、昔、『ゲーデル、エッシャー、バッハ―あるいは不思議の環 』(1985年、白揚社)という数学の本をかじったときに出てきた言葉のような気もするが、そういう数学的な言語と思えばよいだろうか。形式言語も、一種の言語といえるだろうが、自然言語とは異なる性格のものといえるだろう。そして、これらの言語の中のどれを用いて記述されているかを明示することは役に立つとしている。実際、同じ文字の並びが別の言語では異なる意味を持つことがあるので、これは役に立つと思って間違いないだろう。

 「この属性の値は、言語識別のためのタグ [IETF RFC 1766]、またはIETF標準化トラックの後継規定で定義される言語識別コードとする」は、JIS版では [IETF RFC 1766]ではなく、[IETF RFC 3066]と記述されている(次の仕様抜粋を参照)。これは、RFC 1766の新版としてRFC 3066が出てきたことに対応したものである。これらは同じ仕様の旧版と新版に当たる。つまり、RFC 1766の「IETF標準化トラックの後継規定」がRFC 3066ということになる。この2つは、どちらも“Tags for the Identification of Languages”という名前を持っているだけでなく、RFC 3066には“Obsoletes: 1766”という記述が含まれている。これがRFC 1766の新しい版であることを示している。そして、さらに将来RFC 3066の後継規定が生まれるかもしれない。この規定は、それも視野に入れた記述となっている。

言語の識別と、国や地域の識別

 次の疑問は、RFC 1766やRFC 3066がいったい何をするものであるか、である。それが次の「Note」(備考)で説明されている。

Note:

[IETF RFC 1766] tags are constructed from two-letter language codes as defined by [ISO 639], from two-letter country codes as defined by [ISO 3166], or from language identifiers registered with the Internet Assigned Numbers Authority [IANA-LANGCODES]. It is expected that the successor to [IETF RFC 1766] will introduce three-letter language codes for languages not presently covered by [ISO 639].

[IETF RFC 3066]タグは、[ISO 639]で定義される2文字の言語コード、[ISO 3166]で定義される 2文字の国コード、またはインターネット割り当て番号主体(Internet Assigned Numbers Authority) [IANA-LANGCODES] に登録された言語識別コードから構成される。

 ここでは更にISO 639やISO 3166という別の規格の名前が登場している。ISO 639は“Code for the representation of names of languages”と呼ばれるもので、アルファベット2文字で言語を識別する名前を規定している。日本語なら“ja”、英語なら“en”である。

 一方のISO 3166は“Codes for the representation of names of countries and their subdivisions”と呼ばれるもので、アルファベット2文字で国や地域を識別する名前を規定している。日本なら“JP”、米国なら“US”である。さらにもう1つ記述されているのは、IANA-LANGCODESというものだが、これは何だろうか。インターネットの各種名前などの登録機関であるIANA(Internet Assigned Numbers Authority)に登録されている言語の名前であるが、これは容易に見ることができる。試しに、en-scouseという言語名のファイルを見てみると、“English Liverpudlian dialect known as 'Scouse'”に対応する名前だと分かった。これは英語のリバプール訛りであるらしい。果たして、これが独立した名前を与えて定義を与えるだけの価値があるものか筆者には分からないが、少なくとも、XML 1.0勧告の正しい仕様にのっとって、ある要素の示す文章が「リバプール訛り」であることを示すことはできる、ということだ。

(Productions 33 through 38 have been removed.)

(生成規則33から38は削除された)

 ここは、ほかの仕様と重複した定義が削除されたものである。次は具体例である。

For example:

<p xml:lang="en">
  The quick brown fox jumps over the lazy dog.
</p>
<p xml:lang="en-GB">
  What colour is it?
</p>
<p xml:lang="en-US">
  What color is it?
</p>
<sp who="Faust" desc='leise' xml:lang="de">
  <l>Habe nun, ach! Philosophie,</l>
  <l>Juristerei, und Medizin</l>
  <l>und leider auch Theologie</l>
  <l>durchaus studiert mit heißem Bemüh'n.</l>
</sp>

 最初の“xml:lang="en"”は英語(en)の指定である。“xml:lang="en-GB"”は、英国(GB)の英語(en)の指定である。3番目の“xml:lang="en-US"”は米国(US)の英語(en)である。4番目の“xml:lang="de"”はドイツ語(de)であることを示している。

 次に記述されているのは、xml:space属性と同じ子孫要素への指定の波及についてである。

The intent declared with xml:lang is considered to apply to all attributes and content of the element where it is specified, unless overridden with an instance of xml:lang on another element within that content.

xml:langで宣言した意図は、この要素の内容の中に現れるほかの要素のxml:lang属性で上書きされない限り、指定した要素のすべての属性と内容に適用される。

 xml:space属性と同様なので、特に説明は必要ないだろう。これは、

<p lang="en">This is a <strong>pen</strong>.</p>

というようなXHTML文書の一部を思い浮かべれば妥当な仕様であることが分かるだろう。もし、xml:lang属性の効果が子孫要素に波及しないとすれば、strong要素にもxml:lang属性を付けなければならない。しかし、同じ文章中なのに、何回も指定しなければならないのはあまりに煩雑すぎる。

 次は、DTDによるこの属性の宣言の例である。

A simple declaration for xml:lang might take the form

xml:lang NMTOKEN #IMPLIED

but specific default values may also be given, if appropriate. In a collection of French poems for English students, with glosses and notes in English, the xml:lang attribute might be declared this way:

<!ATTLIST poem   xml:lang NMTOKEN 'fr'>
<!ATTLIST gloss  xml:lang NMTOKEN 'en'>
<!ATTLIST note   xml:lang NMTOKEN 'en'>

xml:langを次に示すとおり、簡単に(デフォルト値を与えずに)宣言してもよい。

(例)

必要ならば、特定のデフォルト値を与えてもよい。英語を母語とする学生用のフランス語の詩集では、説明(gloss要素)および注(note要素)を英語で記述すれば、属性xml:langを次のとおりに宣言することとなる。

(例)

 ここでは、以下のような指定を宣言している。

  • poem要素のxml:lang属性の値はフランス語(fr)
  • gloss要素のxml:lang属性の値は英語(en)
  • note要素のxml:lang属性の値は英語(en)

 このような定義を与えておけば、XML文書中でいちいち言語を指定することなく、要素ごとに適切な言語指定が行われることになる。

 さて、今回はこれで終わりである。これでXML 1.0勧告の中の「2 Documents」(2. 文書)のセクションを読み終えることができた。かなり泥臭い話も含まれていて大変だったと思うが、それもこれで終わりである。次回からは、「3. Logical Structures」(3. 論理構造)に入っていくことになる。こちらはXML文書の論理構造を扱うことになるので、少しはきれいな世界を見られるはずである。ぜひ、こちらも読んでいこう。

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


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

注目のテーマ

HTML5+UX 記事ランキング

本日月間