title 要素に文字参照は使用できるのか ?

http://hxxk.jp/2006/01/25/2301

記事データ

投稿者

望月真琴

投稿日時

2006-01-25T23:01+09:00

タグ
概要

Q. title 要素内に文字実体参照ないし数値文字参照を使用できますか ? A.できます。

リプライ

リプライはまだありません。

記事本文

Re: はてなブックマーク日記 - 特定のサイトがブックマークできない件について

はてなブックマーク - 最近の人気エントリー経由で知ったはてなブックマーク自体の不具合のアナウンス。

現在はてなブックマークが内部で利用しているソフトウェア不具合が原因で、幾つかのサイトがブックマークできない状態となっております。

具体的には、HTML の title 要素に実体参照の ' ' が含まれているサイトなどです。

  というのは文字実体参照ではなく数値文字参照にあたります。 ( 私も明確に理解したのは最近でしたが。)

Character entity references in HTML 4 に仕様が示されていますが、 no-break space = non-breaking space を文字実体参照で表す場合は   ではなく &#nbsp; という記述になりますので、 「 HTML の title 要素に数値文字参照の ' ' が含まれているサイトなどです。」 と書く方が記述として正確になります。

現在は記述が修正されています。 対応ありがとうございます。

Re: はてなブックマーク - AAぶろぐ_仏苦魔悪

そして、はてなブックマーク日記 - 特定のサイトがブックマークできない件について寄せられたブックマークコメントの中で気になったものが一点。

[はてな][はてブ]てゆーかtitle要素内に実態参照ってどうなのだろうか

高橋雅奇さん ( はてなブックマーク - AAぶろぐ_仏苦魔悪 ) って、 AAぶろぐ_仏苦魔悪 / W3C で分類されているブックマークやそれに付随するコメントを見る限り、 仕様を蔑ろにするような方ではないと思うのですが……。 仕様書や DTD を見れば答えは明白なのです。

次の項以降で詳述しますが、 title 要素内に文字参照を用いることは特に問題はありません。 はてなブックマーク内部のシステムにどういった不具合があるか分かりませんが、これはサイト製作者側には瑕疵は無いと考えて良いでしょう。

それにしても、はてなブックマークのコメントで疑問を呟かれていた場合、その疑問を抱いた方に確実に回答をお届けする手段って無いですよね。 その方のブックマークページからその方のサイトへのリンクがあって、そこから連絡先を探すという手段もありますが、その方のサイトへのリンクが 100% 書かれているとは限りません。 かと言ってコメントの為にブックマークしても、回答をお届けしたい方がエントリページ ( http://b.hatena.ne.jp/entry/ で始まる URI のページ ) を見ていなければ伝わりませんし。 その辺りにブックマークコメントの難しさが潜んでいるような気がします。

HTML 4.01 Transitional DTD を読み解く

閑話休題。 title 要素に文字参照を用いることができるかどうかという件ですが、 title 要素が DTD でどのように定義されているかを見れば答えにつながることが書いてあります。

はてなブックマークのエントリページは DTD 宣言が無いために、どのバージョンの HTML or XHTML にも属しません。 しかし、各ユーザのページでは <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> という宣言がなされているので、 HTML 4.01 Transitional DTD を見てみましょう。 title 要素については、次に引用する記述で定義されています。

<!ELEMENT TITLE - - (#PCDATA) -(%head.misc;) -- document title -->
<!ATTLIST TITLE %i18n>

これだけ見ても、何について書いてあるのかすぐ理解できる方はそう多くないと思います。 そこで、ごくごく簡単なDTDの説明を参考に、各部分の意味を考えてみましょう。

<!ELEMENT TITLE

これは TITLE という名前の要素を宣言する記述の開始部分です。

- -

左が開始タグ、右が終了タグについてで、 - が省略不可、 O が省略可(Omission)を表します ということですので、 title 要素の開始タグ・終了タグはどちらも省略不可であると示されていることになります。

(#PCDATA) -(%head.misc;)

内容モデルが #PCDATA であることを示し、 head.misc として実体宣言されているものは出現してはいけないと示されています。 その head.misc は <!ENTITY % head.misc "SCRIPT|STYLE|META|LINK|OBJECT" -- repeatable head elements --> と宣言されているため、

  • script 要素
  • style 要素
  • meta 要素
  • link 要素
  • object 要素

が出現してはならないということになります。

<!ATTLIST TITLE

これは TITLE という名前の要素が持つことのできる属性を宣言する記述の開始部分です。

%i18n

i18n として実体宣言されているもの、すなわち

<!ENTITY % i18n
 "lang        %LanguageCode; #IMPLIED  -- language code --
  dir         (ltr|rtl)      #IMPLIED  -- direction for weak/neutral text --"
  >

と宣言されている部分のことで、 lang 属性と dir 属性のことを指します。 よって、 title 要素には lang 属性および dir 属性を指定することができます。

ここで注意しなければならないのは、 title 要素が head 要素の子要素である点です。 title 要素は <!ENTITY % head.content "TITLE & ISINDEX? & BASE?"> という実体宣言に含まれ、その %head.content は <!ELEMENT HEAD O O (%head.content;) +(%head.misc;) -- document head --> という要素宣言に含まれています。 これは head 要素内には %head.content が 1 回だけ出現し、 %head.misc が子孫にわたって出現して良いということを示しています。

よって、もし title 要素が <!ELEMENT TITLE - - (#PCDATA) -- document title --> のような宣言をされていた場合は、親要素で出現して良いとされている %head.misc が要素モデル内に含まれることを許容することになります。 そこで、 title 要素の要素宣言内で -(%head.misc;) と記述することで、 %head.misc が出現してはならないということを示しています。

同様に、 head 要素が含まれている実体宣言を探してみると、 <!ENTITY % html.content "HEAD, BODY"> という実体宣言が見つかります。 そしてその実体宣言が含まれる要素宣言は <!ELEMENT HTML O O (%html.content;) -- document root element --> という html 要素の宣言です。 これを逆の順番で考えると、

  1. HTML 4.01 Transitional DTD において、 html 要素には %html.content ( head 要素を 1 つ、その後に body 要素を 1 つ ) が 1 回だけ出現する
  2. head 要素には %head.content ( title 要素が 1 つと、 isindex 要素および base 要素がそれぞれ 0 または 1 つ。順序は任意 ) が 1 回だけ出現し、 %head.misc ( script 要素、 style 要素、 meta 要素、 link 要素、 object 要素のうちのどれか 1 つ ) が子孫にわたって 0 または複数回出現する
  3. title 要素には #PCDATA が出現し、親要素である head 要素に出現する %head.misc は出現してはならない

ということになり、これをまとめると title 要素には #PCDATA しか出現してはならないということになります。

#PCDATA とは何なのか

では、 title 要素に配置される #PCDATA とは何のことを指すのか ? #PCDATA (構文解析対象文字データ)@ばけらの HTML リファレンス(未完成) が非常に参考になります。

PCDATA は Parsed Character Data の略で、「構文解析対象文字データ」です。 Parsed というのは SGML 的に解釈 (パース) されるということを意味します。 このデータ型は任意の長さを持つ (長さゼロでも良い) 任意のテキストですが、以下のような特徴を持ちます。

  • 文字参照は展開されて対応する文字に置き換えられる。たとえば &amp; と書くと & に置き換えられます。
  • マークはマークとして解釈される。たとえば < はタグの開始区切り子と見なされます (当然そこで #PCDATA は終了しているものとみなされます)。また、<!-- --> を書けば注釈宣言とみなされ、その中身はコメントとして無視されます。

CDATA (文字データ)@ばけらの HTML リファレンス(未完成)も合わせて読むと分かりやすいのですが、大雑把に言うと文字参照が展開されるテキストだということです。 ( では CDATA は文字参照がされないテキストなのかと言うと、 CDATA についても属性値として扱われる場合は文字参照が展開されるため、 CDATA = 文字参照が展開されないテキストとは一概に言えないことに注意してください。 )

他のバージョンの HTML or XHTML ではどうか

前 2 項は HTML 4.01 Transitional DTD を元に考えてみましたが、他のバージョンの HTML or XHTML はどうでしょうか。 それぞれの DTD から関係する部分だけを抜粋して並べてみましょう。

HTML 4.01 Transitional DTD
<!--================ Document Structure ==================================-->

<!ENTITY % html.content "HEAD, BODY">

<!ELEMENT HTML O O (%html.content;)    -- document root element -->

<!--================ Document Head =======================================-->
<!-- %head.misc; defined earlier on as "SCRIPT|STYLE|META|LINK|OBJECT" -->
<!ENTITY % head.content "TITLE & ISINDEX? & BASE?">

<!ELEMENT HEAD O O (%head.content;) +(%head.misc;) -- document head -->

<!ELEMENT TITLE - - (#PCDATA) -(%head.misc;) -- document title -->
HTML 4.01 Frameset DTD
<!--================ Document Structure ==================================-->

<![ %HTML.Frameset; [
<!ENTITY % html.content "HEAD, FRAMESET">
]]>

<!ELEMENT HTML O O (%html.content;)    -- document root element -->

<!--================ Document Head =======================================-->
<!-- %head.misc; defined earlier on as "SCRIPT|STYLE|META|LINK|OBJECT" -->
<!ENTITY % head.content "TITLE & ISINDEX? & BASE?">

<!ELEMENT HEAD O O (%head.content;) +(%head.misc;) -- document head -->

<!ELEMENT TITLE - - (#PCDATA) -(%head.misc;) -- document title -->
HTML 4.01 Strict DTD
<!--================ Document Structure ==================================-->
<!ENTITY % html.content "HEAD, BODY">

<!ELEMENT HTML O O (%html.content;)    -- document root element -->

<!--================ Document Head =======================================-->
<!-- %head.misc; defined earlier on as "SCRIPT|STYLE|META|LINK|OBJECT" -->

<!ENTITY % head.content "TITLE & BASE?">

<!ELEMENT HEAD O O (%head.content;) +(%head.misc;) -- document head -->

<!ELEMENT TITLE - - (#PCDATA) -(%head.misc;) -- document title -->
XHTML 1.0 Transitional DTD
<!--================ Document Structure ==================================-->

<!-- the namespace URI designates the document profile -->

<!ELEMENT html (head, body)>

<!--================ Document Head =======================================-->

<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*">

<!-- content model is %head.misc; combined with a single
     title and an optional base element in any order -->

<!ELEMENT head (%head.misc;,
     ((title, %head.misc;, (base, %head.misc;)?) |
      (base, %head.misc;, (title, %head.misc;))))>

<!ELEMENT title (#PCDATA)>
XHTML 1.0 Frameset DTD
<!--================ Document Structure ==================================-->

<!-- the namespace URI designates the document profile -->

<!ELEMENT html (head, frameset)>

<!--================ Document Head =======================================-->

<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*">

<!-- content model is %head.misc; combined with a single
     title and an optional base element in any order -->

<!ELEMENT head (%head.misc;,
     ((title, %head.misc;, (base, %head.misc;)?) |
      (base, %head.misc;, (title, %head.misc;))))>

<!ELEMENT title (#PCDATA)>
XHTML 1.0 Strict DTD
<!--================ Document Structure ==================================-->

<!-- the namespace URI designates the document profile -->

<!ELEMENT html (head, body)>

<!--================ Document Head =======================================-->

<!ENTITY % head.misc "(script|style|meta|link|object)*">

<!-- content model is %head.misc; combined with a single
     title and an optional base element in any order -->

<!ELEMENT head (%head.misc;,
     ((title, %head.misc;, (base, %head.misc;)?) |
      (base, %head.misc;, (title, %head.misc;))))>

<!ELEMENT title (#PCDATA)>
XHTML 1.1 DTD ( xhtml-struct-1.mod )
<!-- html: XHTML Document Element ...................... -->

<!ENTITY % html.element  "INCLUDE" >
<![%html.element;[
<!ENTITY % html.content  "( %head.qname;, %body.qname; )" >
<!ENTITY % html.qname  "html" >
<!ELEMENT %html.qname;  %html.content; >
<!-- end of html.element -->]]>

<!-- head: Document Head ............................... -->

<!ENTITY % head.element  "INCLUDE" >
<![%head.element;[
<!ENTITY % head.content
    "( %HeadOpts.mix;, %title.qname;, %HeadOpts.mix; )"
>
<!ENTITY % head.qname  "head" >
<!ELEMENT %head.qname;  %head.content; >
<!-- end of head.element -->]]>

<!-- title: Document Title ............................. -->

<!-- The title element is not considered part of the flow of text.
     It should be displayed, for example as the page header or
     window title. Exactly one title is required per document.
-->

<!ENTITY % title.element  "INCLUDE" >
<![%title.element;[
<!ENTITY % title.content  "( #PCDATA )" >
<!ENTITY % title.qname  "title" >
<!ELEMENT %title.qname;  %title.content; >
<!-- end of title.element -->]]>
XHTML Basic DTD ( xhtml-struct-1.mod )
<!-- html: XHTML Document Element ...................... -->

<!ENTITY % html.element  "INCLUDE" >
<![%html.element;[
<!ENTITY % html.content  "( %head.qname;, %body.qname; )" >
<!ENTITY % html.qname  "html" >
<!ELEMENT %html.qname;  %html.content; >
<!-- end of html.element -->]]>

<!-- head: Document Head ............................... -->

<!ENTITY % head.element  "INCLUDE" >
<![%head.element;[
<!ENTITY % head.content
    "( %HeadOpts.mix;, %title.qname;, %HeadOpts.mix; )"
>
<!ENTITY % head.qname  "head" >
<!ELEMENT %head.qname;  %head.content; >
<!-- end of head.element -->]]>

<!-- title: Document Title ............................. -->

<!-- The title element is not considered part of the flow of text.
     It should be displayed, for example as the page header or
     window title. Exactly one title is required per document.
-->

<!ENTITY % title.element  "INCLUDE" >
<![%title.element;[
<!ENTITY % title.content  "( #PCDATA )" >
<!ENTITY % title.qname  "title" >
<!ELEMENT %title.qname;  %title.content; >
<!-- end of title.element -->]]>

細かい解説は割愛しますが、共通して言えることはどのバージョンにおいても title 要素の内容は #PCDATA のみであるということです。 なお、 ISO-HTMLDTD は ftp://ftp.cs.tcd.ie/isohtml/15445.dtd に置かれてありますが、内容を見ることはできませんでした。 DDT's Room:JIS-HTMLに関する私的メモ - TITLE要素によると、 <!ELEMENT TITLE - - (#PCDATA) -(LINK | META | STYLE) > のように、やはり #PCDATA のみが title 要素内に出現する内容として定義されているようです。

まとめ

まとめると、現在勧告されている HTML or XHTML において、 title 要素に出現することができる内容は文字参照が展開されるテキストであるということになります。 Re: はてなブックマーク - AAぶろぐ_仏苦魔悪にて「 title 要素内に文字参照を用いることは特に問題はありません」と述べましたが、前 3 項のような根拠によって成り立っています。

トラックバック送信先

はてなブックマーク日記 - 特定のサイトがブックマークできない件について

文中に「実体参照」と書いてありますが、この場合は「数値文字参照」と書くべきです。

リプライ

リプライはまだ送られていないか、管理者の承認待ち状態です。

この記事に対するご意見やご質問、ご感想などありましたらこのフォームに簡潔に記入して下さい。 簡潔に記入できない場合や、関連記事にてご意見をお寄せいただく場合は、ご自身の weblog にて記事を書かれた上で あてにトラックバックとして送信してください。

記入フォーム

補足情報

著作、講演、制作実績など