2001年12月 - マーク付けノート

2001-12-26

更新

ディレクトリを再々構築しました。旧リソースも放置してありますが、それらはそのうち書き直します。

一般実体参照と文字参照

もう少し詳しい解説を書く予定ですが、取り敢えずのメモ。方々の HTML 解説を見て思うことなのですが、まともなサイトであっても参照まわりには誤りがある、ということが多いような。何故なんでしょうか。

非常に多いのは、一般実体参照文字参照を混同しているケースです。一般実体参照というのは例えば & のようなものであり、文字参照というのは & のようなものです。

文字参照は (DTD 内を含め)文書の至る所で前提抜きに使用できます。これに対して一般実体参照の場合は、参照の出現以前に実体が宣言されている必要があります (XML の場合は若干異なる*1)。例えば HTML 4.01 において "&" で参照される実体は、DTD 中で以下のように宣言されています。

<!ENTITY amp CDATA "&#38;"  -- ampersand, U+0026 ISOnum -->

"&amp;" という一般実体参照があれば、パーザはこれを "&#38;" という文字列(実体)に置換する、という意味です (CDATA キーワードは、実体を CDATA として扱えという指定。このキーワードを使えない XML では、"amp" の実体を "&#38;#38;" などとして定義しなければならない)。

このように(一般)実体参照というのは、定義された何らかの実体を参照するから実体という名が付いている訳です。"&#38;" などは実体を参照している訳ではありませんから、これを"実体参照"と呼ぶのは誤りです。同様に、"&amp;" などは常に文字データを参照しているわけではありませんから、これを文字参照と呼ぶのも誤りです(実際 "&amp;"文字データではなく "&#38;" という文字参照を参照している)。

*1:SGMLの Annex (K.3.4.2) では、SGML宣言内でも一般実体を定義できるようになっています。XMLはこの仕組みを(仮想的に)利用しており、amp / lt / gt / quot / apos の五つの実体参照は前提なしに記述することができます。

# 2003-11-10 追記

ただし、HTML4 などの仕様では「文字参照」と「文字参照を実体とする実体参照(=文字実体参照)」をひっくるめて「文字参照」と表現しているので、"&amp;" のようなものを「文字参照」と表現することは一概に誤りとは言えないと思います。(この辺のことは、当時北村曉さんにご指摘いただきました。)

# 2003-11-18 追記

[8] HTML4 の文字参照についての規定 によれば、 HTML では、文字参照は (1) 数値文字参照 : 10進または16進 (2) 文字実体参照の2つの形で現れるとされています。一見 SGML の定義とは異なるように思えますが、(規定中でわざわざ「SGML 文字参照」と言っていることを見ても) そうではなく、文字実体参照は文字参照を値に持つ実体であることを考えれば矛盾はないことが分かります。

"In HTML, character references may appear in two forms:" ではなく Character references in HTML may appear in two forms: なのが若干引っかかるのですが、言われてみれば確かに HTML4 の意図的にはその解釈の方が正しいような気がします。これは僕の読解力不足でした。

つまり、HTML4 は「HTML では文字参照は次のように記述できる」ということを述べているだけであって、HTML における「文字参照」という用語の定義をしているわけではない、と。

そうだとするならば、やはり「文字実体参照は文字参照の一種である」と表現するのは誤りで、「文字参照は文字実体参照の形でも記述できる」というのが正しい表現と言えそうです。

属性と参照

もう一つ非常に誤りが多いのが属性の構文に関する解説で、属性値中の & は実体参照の開始と見做される、などというのは誤りです。

例えば a 要素の href 属性の値は CDATA です。CDATA というのは「解析不要の文字データ」のことですから、もしも href 属性の./samp.cgi?foo&amp;hoge だったとすると、これは "./samp.cgi?foo&amp;hoge" という URI に対してのリンクであると見なされます。

しかし、注意すべきことですが、<a href="./samp.cgi?foo&amp;hoge">sample</a> と記述した場合、これは "./samp.cgi?foo&hoge" という URI に対してのリンクであると見なされます。

禅問答みたいな感じですが、要するに何を言いたいかのというと、LIT (引用符)で括られている文字列は属性値ではない、ということです。言い方を変えると、屡々属性の解説として示される 属性名="属性値" という構文は誤りです。

正しい属性の構文は以下の通り(一部略)。

属性名="RCDATA"

但し、属性値が名前文字だけのときには、以下のように記述することもできます。

属性名=属性値

属性を 属性名="RCDATA" の形式で記述した場合、パーザはLITで括られている文字列を RCDATA として解析します。RCDATA として解析するとは、"<"などはタグの開始と認識しないが、文字参照や実体参照は一度展開する、ということです。パーザは、こうして一度解析された文字列属性値として保持するのです。

一方 LIT を略した場合には、属性名= に続く文字列が直接属性値として保持されることになる訳です(これは属性名を省略して <table border> などと記述した場合も同様です)。

属性値の形式が CDATA なのに、何故 title="R&amp;B" の '&amp;' は展開されるのか? という疑問を抱いていた方も、これですっきりしたのではないでしょうか。というか、僕はすっきりしました。

これもそのうち、もう少し詳しく。

# 2003-11-10 追記

ただし、XML 1.0 では SGML でいう「属性値リテラル」を「属性値」と表現しているので、これも一概には誤りとは言えないと思います。

2001年12月27日

属性と参照(続き)

DTD を読まない人には上の話の意味がよく解らないと思いますが、DTD の読み方を学んでいる最中に誰もが抱く疑問があるんです。title="R&amp;B""&amp;" は展開されるのに、何で属性値のデータ形式が CDATA なんだ、という。僕はこれについてきちんと解説しているサイトを見たことがないので、メモとして書いておきました。

上に書いたことは、言ってみればかなり下らないことであると思います。初めから「属性は attr="foo" のように記述する。"foo" の参照を展開したものが attr の属性値となる。」と説明されていれば、「そうなんですか」で済む話ですから。ところが、殆どの人は "foo" が属性値である、と教わっている。そのために上記のような疑問が生じる訳で。

HTML 4.01 の仕様書からして怪しい記述がなされているために、妙な"誤解"が広まってしまったような感じですが、本来は非常に基礎的なレベルの問題であったように思います。

スタイルシートの話

Mozilla 0.9.7 で御覧の方には判らない筈だと思いますが、一応スタイルシートは記述してあります。お察しの通り、サーバが正しい MIME タイプを吐いていないようです。

情報基礎Bのうち、スタイルシートを教えている授業は一コマのみ。その授業でも style 要素と style 属性しか教えていない以上、多分誰も困らないのでしょう。僕も別に困らないので放置しておきます。見難いと感じた人はブラウザのデフォルトスタイルをいじって下さい、ということで。

# 2003-11-10 追記

これは、都立大の PCC サーバ (pcc.metro-u.ac.jp) 当時の話です。

この文書のステータス

URI
http://www.satoshii.org/markup/notes/2001/12
初版
2001-12-26
最終更新
2004-01-11
著者
石川哲志
Copyright © 2001, 2003, 2004 Satoshi ISHIKAWA, All Rights Reserved.