血統の森+はてな

旧はてなダイアリーの自動インポートによるアーカイブです。

XHTML5と文字参照

結論から言うと、XHTML構文で名前文字参照(HTML4で言うところの文字実体参照)は使用を避けた方が良いかもしれない、と言う話。リテラルに文字を書いたほうがよい(どうしてもというなら、数値実体参照で)、というお話。

適当にぐぐって見つけたページ(XHTML5で実体参照を使う方法 - 泥のように)が大体合っていますが、微妙に舌足らずな気もするので一応メモ。もっとも、webでXHTML5を使うことは滅多にないと思うので、もっぱらEPUB3のリーディングシステム(≒WebKit?)でどうなるのか、ぐらいしか思いつきませんが。

なお、XMLについてはよくわかっていないので全然あさってなことを書いているかもしれませんのであしからず。

本題に入る前にまず文字参照(Character references)のおさらい。HTML4では、

と呼ばれていたけれども*1 *2HTML5では、

  • 名前文字参照(Named character references)
  • 10進数の数値文字参照(Decimal numeric character reference)
  • 16進数の数値文字参照(Hexadecimal numeric character reference)

と呼ばれている*3 *4。数値文字参照は10進と16進が存在することが明示され、文字実体参照は名前実体参照という呼び方になった。

さて、この"名前実体参照"ですが、HTML5SGML応用ではないので、DTDに定義することなく仕様書そのものに名前実体参照を定義すればよいわけです。実際HTML5仕様では、8.5 名前文字参照にすべて列挙されています。ところが、XHTML5はDTDが存在しないので、XML1.0仕様で定義されている<>&'"*5以外の名前実体参照は整形式性制約に違反する(はず*6)。なので、少なくともFirefoxではエラーとして報告される。

具体的には、

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta charset="utf-8" />
<title>文字参照の検証テスト</title>
</head>
<body>
<p>test &copy;</p>
</body>
</html>

とでもして、拡張子.xhtmlあたりで保存して(application/xhtml+xmlになるようにして)Firefoxで見てみると、

といった具合でFirefoxでは怒られる。ではどうするか?というと

  1. DOCTYPE宣言の中に宣言を直接書く
  2. DOCTYPE宣言でDTDを読み込ませる

あたりが解決方法になるだろう(Firefoxでは一応問題ない)。なお、HTML5仕様は、

XML文書は必要に応じてDOCTYPEが含んでもよいが、DOCTYPEはこの仕様に準拠する必要はない。この仕様は、公開またはシステム識別子を定義せず、公式なDTDも提供しない。

9 The XHTML syntax ― HTML5 日本語訳

と言っているので、<!DOCTYPE html>に(XML1.0使用の範囲で)自由に付け足ししていいはず。

DOCTYPE宣言の中に宣言を直接書く

たとえば以下のように宣言してしまう。

<!DOCTYPE html [
<!ENTITY copy "&#x000A9;">
]>

これでXMLとして正しく文字参照を解決できるけれども、いちいち必要な名前文字参照を列挙しなければならないので面倒、と。

DOCTYPE宣言でDTDを読み込ませる

Public Identifiers for entity resolution in XHTML(この記事を書いた時点ではWorking Draft。2016年5月に編集時点では放棄されたNoteであることに注意)で示唆されるように、

<!DOCTYPE html PUBLIC "-//W3C//ENTITIES HTML MathML Set//EN//XML" "http://www.w3.org/2003/entities/2007/htmlmathml-f.ent">

と、参照の宣言を全部読み込ませてしまう。ただし、IE11やGoogle Chrome32だと文字が出なかったり、エラーが出たりするので実用的ではない…。



まとめ?

XHTML5において、XMLの文法上正しく処理させようとするのは手間がかかるまたはウェブブラウザの対応が怪しいため、名前文字参照を避けてリテラルに文字を記述するかそれが難しいのであれば数値文字参照を代わりに使用したほうがよい。