▼属性指定を分解しよう▼

$Id: attvalspec.html,v 1.7 2001-07-02 09:09:59+09 kabe Exp $


いきなり例題から分解にかかりましょう。 かっこ内は JIS X4151 の見出し番号。

	<A href="http://www/cgi-bin/gateway?volts=10&amp=0.4">getit</A>
	|========================要素(6.3)============================|
	|==================開始タグ(6.4)=====================||===||==|
	<                                                     内容 終了タグ
	|stago
	 (なし)
	 文書型指定(6.7)
	 A
	 |共通識別子指定(6.8)
	   href="http://www/cgi-bin/gateway?volts=10&amp=0.4"
	   |=================属性指定並び(6.9)==============|>
	                                                     |tagc
文書型指定は一般のSGML文書でもあまり使われません。 HTMLでは そもそもSGML宣言で "CONCUR NO" となっているので使えません。
属性指定並びのうちの個々が属性指定となります。(例では1個だけなので結局全体)
	   href="http://www/cgi-bin/gateway?volts=10&amp=0.4"
	   |=================属性指定(6.9)==================|
	   href
	   |==| 名前 (属性名(10.3)、のはず)
	       =
	       |vi
	        "http://www/cgi-bin/gateway?volts=10&amp=0.4"
	        |===============属性値指定(6.9.3)===========|
この属性値指定は lit `"' でくくられているので、 属性値表記と解釈されます。
	        "http://www/cgi-bin/gateway?volts=10&amp=0.4"
	        |===============属性値表記(6.9.3)===========|
	        "
	        |lit
	         http://www/cgi-bin/gateway?volts=10&amp=0.4
	         |===========置換可能文字データ(8.1)=======|"
	                                                    |lit
置換可能文字データは、 文字参照 (&#文字番号)・一般実体参照 (&名前)を 展開します。 (引数実体参照 (%名前;)(8.4.4) は展開されないので、 %7E とかはそのまま)
	         http://www/cgi-bin/gateway?volts=10&amp=0.4
	         |======データ文字*(8.2)==========|    |==|データ文字*
	                                            &amp
	                                            |==|一般実体参照(8.4.4)

最終的な属性値は http://www/cgi-bin/gateway?volts=10&=0.4 となります。 これを URL としてサーバーへHTTP要求が投げられます。

なので、URLとして http://www/cgi-bin/gateway?volts=10&amp=0.4 を送りたい場合は `&' を展開して
	<A href="http://www/cgi-bin/gateway?volts=10&amp;amp=0.4">
と書きます。

SGML的には、さらにこの属性値が属性定義の宣言に合っているかどうか チェックします。が <A HREF> は CDATA (文字データ) と宣言されているので

	<!ATTLIST A
		HREF CDATA #IMPLIED
	>
おおかた何を突っ込んでもいいことになります。

一般実体参照の展開がイヤであれば属性値指定(6.9.3)を属性値表記ではなく `"' のない属性値(6.9.4)として書けばいいんですが、 問題になるような URL には余裕で名前文字 (平たくいうと[A-Za-z0-9.-]) 以外を含んでいるのでダメです。(6.9.3.1)


くそまじめなブラウザ(SGML系のブラウザ)であればこういった処理を丁寧に やるんでしょうけど、実際には & を展開せずに直接 HREF に 突っ込んでいる人が多いので、ブラウザもそれに対応すべく いいかげんな処理をしていることがあります。 結局ブラウザ依存なので、安全側にいくなら 最初から & を使わない 方法もあります。 (もちろん「腐れたブラウザが悪い」「ほげブラウザで見てください」でも可能)


混乱する例

	<LI><A href="/users/hoge/index.html">Home1</A>
	<LI><A href="/users/hoge&#47;index.html">Home2</A>
	<LI><A href="/users/hoge%2Findex.html">Home3</A>
	<LI><A href="/users/hoge&#37;2Findex.html">Home4</A>

URLに変換後、サーバーに送られるHTTP要求は

サーバーがどこのファイルを返すかは、実はサーバー・設定依存。 (ファイルでさえないかもしれない)

まあ普通は いずれも DocumentRoot/users/hoge/index.html が返されるんでしょうけど、サーバーがMacintoshだったりすると3番目は DocumentRoot:users:hoge/index.html だったりするかも。

返されたHTMLの中で、さらにこんなのがあると

	<A href="toc.html">Table of Contents</A>
どこに飛ばされるかわかんなかったりする。(考えてみよー)


参考文献


かべ@sra-tohoku.co.jp