記事本文
次に書く記事のための記事
HTML ( というか SGML ) では「要素によっては開始タグや終了タグを省略することができる」ということはある程度知られていることだと思いますが、この次に書く記事でそのことに触れようと思っていますので、ここで解説しておきます。
何故終了タグを省略できるか
今回の解説では ul 要素および li 要素を例にとってみます。
HTML のベースとなる SGML では省略タグ機構という仕組みが定められており、それは
SGML宣言で OMITTAG YES と宣言されている時に限って有効
となっています。
HTML においても OMITTAG YES と宣言されており、いくつかの条件を全て満たしている場合にのみ開始タグや終了タグを省略できます。
( SGMLsec6_0.html, Latest updated 1998.01.19 - 6.3.1 最小化―タグの省略も併せて参照してください。 )
さて、その「いくつかの条件」とは何か。 マニアックな文法論議 - SGML の省略タグ機構によると、
OMITTAG YES だからといって、何でも好き勝手に省略できるわけではありません。 タグの省略は、以下の全てを満たす場合のみ可能です。
- DTD で、そのタグが省略可能であるとされている。
- 文脈上、そのタグの省略が自明である。
- 必須の属性を持つ要素の開始タグではない。
- その要素の中身が EMPTY ではない。
というのが条件であるようです。 次に HTML 4.01 Strict DTD にて ul 要素と li 要素の項を見てみると、以下のように書かれています。 ( HTML 4.01 Transitional DTD でもほぼ同じ記述です。 )
<!-- Unordered Lists (UL) bullet styles --> <!ELEMENT UL - - (LI)+ -- unordered list --> <!ATTLIST UL %attrs; -- %coreattrs, %i18n, %events -- > <!ELEMENT LI - O (%flow;)* -- list item --> <!ATTLIST LI %attrs; -- %coreattrs, %i18n, %events -- >
この li 要素の記述を先述の条件に当てはめてみると、
- - O ( 開始タグ省略不可、終了タグ省略可 ) とされている。
- 必須の属性を持つ要素ではない
- 要素の中身は (%flow;)* であり、 EMPTY ではない。
ということになり、 4 つの条件のうち 3 つを満たしています。 次に、「文脈上、そのタグの省略が自明である。」を検証するにはどうすればいいか。 SGMLsec6_0.html, Latest updated 1998.01.19 - 6.3.1 最小化―タグの省略によると、
- 6.3.1.1 開始タグの省略
要素の開始タグは, その要素が文脈上必須であって, しかもそこに現れうる他の形式の要素がどれも文脈上任意選択である場合, 省略することができる。 ただし, 次の (1)~(2) のときを除く。
- (1) その要素に必須の属性があるか, その要素が宣言内容をもつとき
- (2) その要素の実現値の内容が空であるとき
( 中略 )
- 6.3.1.2 終了タグの省略
要素の終了タグは, 次の (1)~(3) の直前に位置する場合, 省略することができる。
- (1) SGML 文書実体又は SGML 部分文書実体の終わり
- (2) 他の開いている要素の終了タグ
- (3) その要素の内容となりえない要素又は SGML 文字
と示されています。 そこで、まずはタグの省略を考えずに、 DTD に従って ul 要素を用いたリストのモデルを考えると、次のように記述できます。
<ul>
<li>リストアイテム A</li>
<li>リストアイテム B</li>
<li>リストアイテム C</li>
</ul>
ここからタグの省略を行っていきましょう。
li 要素は ul 要素または ol 要素 ( transitional DTD の場合はこれに加えて dir 要素と menu 要素 ) の中にしか含めることができませんから、 li 要素は他の li 要素の直接の内容となりえることができません。
よって、 <li>リストアイテム A と記述した後に、また <li>リストアイテム B という記述をしてしまうと、その要素の内容となりえない要素が現れているということになり、その直前の </li> は省略することができます。
よって、先ほどのモデルを以下のように記述しなおします。
<ul>
<li>リストアイテム A <!-- 直後に li 要素が現れるので </li> を省略 -->
<li>リストアイテム B <!-- 直後に li 要素が現れるので </li> を省略 -->
<li>リストアイテム C</li>
</ul>
次に <li>リストアイテム C</li> の部分ですが、直後に他の開いている要素の終了タグ </ul> が現れているので、 <li>リストアイテム C というように、 </li> を省略することができます。
よって、省略することができる部分を省略した ul 要素を用いたリストのモデルは以下のように示すことができます。
<ul>
<li>リストアイテム A <!-- 直後に li 要素が現れるので </li> を省略 -->
<li>リストアイテム B <!-- 直後に li 要素が現れるので </li> を省略 -->
<li>リストアイテム C <!-- 直後に </ul> が現れるので </li> を省略 -->
</ul>
以上の点より、 「文脈上、そのタグの省略が自明である。」 と言えると思います。 よって、 li 要素の終了タグは省略してもよいということになります。
ちなみに、 XHTML は SGML ベースではなく XML ベースであるため、終了タグの省略はできません。 Extensible Markup Language (XML) 1.0 - Start-Tags, End-Tags, and Empty-Element Tags に、
[Definition: The end of every element that begins with a start-tag MUST be marked by an end-tag containing a name that echoes the element's type as given in the start-tag:]
のように示されています。
XHTML 1.0 Strict DTD を見てみても、
<!-- list item --> <!ELEMENT li %Flow;> <!ATTLIST li %attrs; >
のように、省略可とか省略不可とかといった記述自体がないことからも分かると思います。

