HTML5の空要素タグの文法
HTML5の空要素タグについては、/ が入っても入っていなくてもどちらでもよいものと認識していた(参照: WHATWG FAQ - 日本語訳 - HTML5.JP)。しかし具体的に仕様を確認したことがまだなかったので、仕様書の9.1.2.1 Start tagsの項を読んでみた。(以下、自分なりの訳も付記してみました)
Start tags must have the following format:
(訳) 開始タグには、以下の書式がなければなりません:
1. The first character of a start tag must be a U+003C LESS-THAN SIGN character (<).
(訳) 1. 開始タグの先頭文字は U+003C LESS-THAN SIGN (<) でなければなりません。
2. The next few characters of a start tag must be the element's tag name.
(訳) 2. 開始タグの次の数文字が要素のタグ名でなければなりません。
3. If there are to be any attributes in the next step, there must first be one or more space characters.
(訳) 3. 次の段階に何か属性があれば、最初に、1つ以上の空白文字がなければなりません。
4. Then, the start tag may have a number of attributes, the syntax for which is described below. Attributes may be separated from each other by one or more space characters.
(訳) 4. そして、開始タグには、幾つかの属性があるかもしれません(その文法は以下で説明されます)。属性は1つ以上の空白文字によって互いに分けられるかもしれません。
5. After the attributes, there may be one or more space characters. (Some attributes are required to be followed by a space. See the attributes section below.)
(訳) 5. 属性の後に、1つ以上の空白文字があるかもしれません。(いくつかの属性は、空白が後に続くことを必要とします。以下の「属性」の項を見てください)
6. Then, if the element is one of the void elements, or if the element is a foreign element, then there may be a single U+002F SOLIDUS character (/). This character has no effect on void elements, but on foreign elements it marks the start tag as self-closing.
(訳) 6. そして、要素が空要素の1つであるか、または要素が外部要素であれば、一つの U+002F SOLIDUS (/) があるかもしれません。この文字は空要素においては何の効果もありませんが、外部要素においては、この文字は開始タグが自身を終了するものであることを示します。
7. Finally, start tags must be closed by a U+003E GREATER-THAN SIGN character (>).
(訳) 7. 最後に、U+003E GREATER-THAN SIGN (>) により開始タグを閉じなければなりません。
……という内容を読んで、以下の3点を確認できた。
/を入れていいのは空要素と外部要素(MathML名前空間とSVG名前空間)に限られる。つまりsrc属性付きのscript要素を<script src="..." />と書くのは不可、ということ。/をどこにでも入れていいわけではない。属性と属性の間に書くのは当然不可。/と、タグを閉じるための>は隣接していなければならない。間に空白等が入ってはならない。
ただ仕様書の文を読んで気になったのだが、この書き方だと、属性が無い場合に要素名の後に任意の空白が入るのが不可になってしまうのではないか、つまり <br /> や <br >のような書き方ができないのではないか、ということだった。空白については上記の3番と5番で説明されているが、どちらも属性がある場合に限定されているように見えるので。
自分の英語の解釈の間違いとかであればいいのだが……。
ところでHTML4では空要素は empty elements だったけれど、HTML5では void elements なのだな。日本語訳は引き続き「空要素」でよかっただろうか。
footer要素内容について確認
HTML5のことを少しづつ知っていこうとしている昨今なのですが、html5の新しい要素 « KuniMemoという記事で、footer要素に関して以下のような説明がされていました。
付録、奥付、ラインセンス合意、索引などはsectionを使うべき。footerを使うべきではない。中にはh1-h6,footer,header,section,articleなどタイトル、セクション関係の要素を入れてはいけない。
感覚的には、付録・奥付などはいかにもfooterの内容として用いられそうに思っていたので、そういう直感が仕様と異なっているのであれば注意しないといけないな、と思いました。が、念のためWHATWGのHTML5仕様(2009年9月9日版)に当たってみたところ、どうもそういう記述が見られないので、また分からなくなってきたのでした。
WHATWGの仕様を見ると、
When the
footerelement contains entire sections, they represent appendices, indexes, long colophons, verbose license agreements, and other such content.
(拙訳: footer要素が丸ごとのセクションを含むとき、それらは付録、索引、長い奥付、詳しい許諾契約、および他のそのような内容を表します)
……と書かれており、先の記事の説明とは逆の意味のようにも見えます。
さらにValidator.nuでfooter要素の中にsection要素、h1要素などを入れたソースをチェックすると、こちらはエラーとしてチェックされる結果となり……。
ということでよく分からなくなってきたので、Twitterにて疑問を投げかけてみたところ、以下の指摘を頂きました。(感謝)
- kits_
footerがsectionやheadingを含めない(validator.nuで確認)というのは仕様のどの辺りだろう。 #html5
- vant
@kits_ それ、先週なくなっちゃいました http://bit.ly/17aDT8
- rh_kimata
@kits_ http://bit.ly/R2LXy 4.4.9 The footer elementのContent modelではなくてでしょうか? #html5
なるほど、先日公開されたところのW3CのHTML5仕様(2009年8月25日版)の方では、footer要素の説明も確かに引用記事にあった通りの説明となっていたけれど、今あるWHATWGの仕様はそこからさらに変更されたものだった、ということでした。なので今のところは、footer要素にも付録、索引等々をセクションとして含めることができる、ということでよさそうです。
前の版の仕様については、内容が大きすぎるfooterを抑止するという意図なのかなとも推測できたので、それはそれで妥当かという気もしていたのですが、やはり文書構成要素の仕様を考えるというのは難しいものだなあと思ったのでした。
XHTML 1.1からHTML 4.01への変換
deadspace #2009-05-20 にてXSLTの問題提議がされていたので、少し考えてみました。かいつまんで言うと、XHTML 1.1からHTML 4.01、HTML4.01からXHTML 1.1へのXSL変換では、単にコピーしただけではうまくいかない箇所がでてくるというものです。
取り敢えずこの記事ではXHTML 1.1文書からHTML 4.01文書への変換について考えてみました。
input.xml :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
<head>
<meta name="robots" content="noarchive"/>
<title>sample document</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<h1>sample document</h1>
<p>foo bar<br/>baz</p>
</body>
</html>
tr2html.xsl :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:h="http://www.w3.org/1999/xhtml"
>
<xsl:output
method="html"
doctype-public="-//W3C//DTD HTML 4.01//EN"
doctype-system="http://www.w3.org/TR/html4/strict.dtd"
/>
<!--
XHTML名前空間に属する要素は、
同じ要素名かつ名前空間に属さない要素に変換
-->
<xsl:template match="h:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<!--
xml:lang属性はlang属性に変換
-->
<xsl:template match="@xml:lang">
<xsl:attribute name="lang">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!--
その他の属性・ノードはそのままコピー
cf. http://www.w3.org/TR/xslt#copying
-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
で、結果は以下の通り。
$ xsltproc --version Using libxml 20703, libxslt 10124 and libexslt 813 xsltproc was compiled against libxml 20632, libxslt 10124 and libexslt 813 libxslt 10124 was compiled against libxml 20632 libexslt 813 was compiled against libxml 20632 $ xsltproc --novalid tr2html.xsl input.xml <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="robots" content="noarchive"> <title>sample document</title> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <h1>sample document</h1> <p>foo bar<br>baz</p> </body> </html>
※ --novalid オプションが無いと、不要な属性(html要素のversion属性、head要素のprofile属性など)が出力文書に現われるので注意。
XSLT 1.0でHTML出力メソッド (<xsl:output method="html"/>) をうまく働かすには、出力する要素が名前空間に属さないことが必要であるようです。以下仕様書和訳の 16.2 HTML 出力メソッド より。
html出力メソッドは、エレメントの展開された名前が null のネームスペース URI を持つ場合を除き、xml出力メソッドと異なる方法でエレメントを出力すべきではない。展開された名前が null 以外のネームスペース URI を持つエレメントは、XML として出力すべきである。 展開された名前が null のネームスペース URI を持つが、ローカルパートが HTML エレメントの名前であると認識されないエレメントは、spanなどの空でないインラインエレメントと同じ方法で出力すべきである。
html出力メソッドは空エレメントのエンドタグを出力すべきではない。 HTML 4.0 の空エレメントは、area、base、basefont、br、col、frame、hr、img、input、isindex、link、meta、およびparamである。 たとえば、スタイルシートに<br/>または<br></br>と記述されたエレメントは、<br>と出力される。
2009年5月10日
埼玉スタジアムへ赴き浦和レッズ対川崎フロンターレの試合を観戦。結果は 2-3 でフロンターレの勝利でした。
PK判定の場面ではジュニーニョの倒れ方が少しふわっとした感じだったので「うまいことファウルをゲットできたのかな」くらいに思っていたのですが、帰宅後にニュース映像を確認してみると、ペナルティエリアの角のところで闘莉王にしっかり足を踏まれてました。目の前に居たのにちゃんと見てなくて御免>ジュニ。ともかくそこで2-2の同点に追いつき、その3分後にカウンターで逆転。常に先行される展開でしたが最後は勝ち切ることができました。
アウェイの埼スタでの試合は一昨年前から毎回観に行っており、あの圧倒的な大サポーターの中、3年連続で勝利を味わえたのは何とも幸運なことであります。願わくは(今年こそ)等々力でも浦和から勝利を挙げたいところ。
敵地での勝利は得たものの代償も大きく、ヴィトール・ジュニオールと横山が警告で次節出場停止、頼りのCB寺田も負傷ということで特にディフェンスが危機的状況にあるフロンターレです。しかしこういう時こそ若手の出てくる機会でもあるわけで、次節のホーム磐田戦は不安でもあり楽しみでもあります。
HTML5仕様書の要素索引を作ってみる
HTML5仕様書を拾い読みしていこうかと思い索引を見てみたら、全然作られてなくてがっかりしたのでありました。取り敢えず要素索引だけでもと思い、目次を元に自分で作成してみました。
ちなみに作成には以下のようなPerlスクリプトを使用しました。もし要素の抜けなどありましたら、何らかの方法でご報告頂ければ幸いです。
# version: 2009-09-11
use strict;
use warnings;
use XML::LibXML;
my $url = 'http://www.whatwg.org/specs/web-apps/current-work/multipage/';
my $parser = XML::LibXML->new;
my $doc = $parser->parse_html_file($url);
#my $doc = $parser->parse_html_file('html5.html');
# 目次から要素説明へのリンク(a要素)を取得
my $anchor_xpath = q{
//a[
(
starts-with(span, "4.")
or starts-with(span, "12.")
)
and contains( substring-after(., "The"), "element")
and code
]
};
my @anchors = $doc->findnodes($anchor_xpath);
# 出力用文書を読み込む
my $doc_out = $parser->parse_fh( \*DATA );
# 要素を出力用文書へ移入
@anchors = map { $doc_out->importNode($_) } @anchors;
# a要素ノードを変更
for my $anchor (@anchors) {
# 要素名と区切り文字以外を削除
for my $node ($anchor->childNodes) {
next if $node->nodeName eq 'code';
next if $node->textContent =~ /(?:,|and)/;
$anchor->removeChild($node);
}
# href属性に絶対URLを設定
my $href = $anchor->getAttribute('href');
$anchor->setAttribute('href', "$url$href");
}
# 要素名でソート
@anchors = map { $_->[0] }
sort { $a->[1] cmp $b->[1] }
map { [ $_, $_->textContent ] } @anchors;
# 出力用文書にアンカーを挿入
my ($ul) = $doc_out->getElementsByTagName('ul');
for my $anchor (@anchors) {
my $li = $doc_out->createElement('li');
$li->appendChild($anchor);
$ul->appendChild($li);
}
# 出力用文書に時刻を挿入
my ($p_mod) = $doc_out->getElementsByTagName('p');
$p_mod->appendChild( $doc_out->createTextNode(scalar localtime) );
# HTMLとして出力
print $doc_out->toStringHTML;
__DATA__
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<title>index of HTML5 elements</title>
</head>
<body>
<h1>index of HTML5 elements</h1>
<p>last-modified: </p>
<ul/>
<p>cf. <a href="http://www.akatsukinishisu.net/itazuragaki/html/index_of_html5_elements.html" lang="ja">HTML5仕様書の要素索引を作ってみる - 徒書</a></p>
</body>
</html>
XML::LibXMLを使ったHTML文書の操作については、XML::LibXMLでHTML文書を扱うの記事でも言及しています。
追記: 2009年4月14日
meta,script,video,audio,datagrid,command,menu,applet,marqueeが抜けていたのを修正しました。- 出力文書についてもDOM操作により作成するよう変更しました。
追記: 2009年8月26日
- Obsolete features の章番号が11から12へ変更されていたのに対応しました。
追記: 2009年9月11日
- "HTML 5"の表記を、空白無しの"HTML5"に改めました。参照: The WHATWG Blog » Blog Archive » Spelling HTML5