倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

Java と XML と空白と (4) : HTML, XML, XHTML の空白

今回は、幾つかのマークアップ言語について、空白の扱いを見ていきます。 ここで見ていくのは次の3つ:

正確にはそれぞれの仕様書を参照してください。

HTML 4.01


仕様書は『HTML 4.01 Specification』。 以下では次の項目を見ていきます:

  • 空白文字
  • 空白の扱い

★空白文字★

Unicode 名前 Java
  ASCII space ' '
	 ASCII tab '\t'
 ASCII form feed '\f'
​ Zero-width space '\u200B'

 carriage return '\r'

 line feed '\n'

★空白の扱い★

  • <pre> 要素下の空白はそのまま
  • <pre> 要素下以外の空白は「単語間の空白 (inter-word space)」に変換される

「単語*1間の空白」は、欧文では普通のスペース (&#x0020;) 、日本語や中国語ではなし、タイ語では「Zero-width word separator (&#x200B;)」だそうです(タイ語分からん)。 「単語間空白」が実際にどのように表示されるかはレンダリングするアプリケーションに依存します。

仕様書全てに目を通しては居ませんが、先頭や後尾の空白をどのように扱うかは見当たりませんでした(少なくとも空白の扱いを書いてある周辺には)。 まぁ、取り除くのが普通でしょうけど。

XML 1.0


仕様書は『Extensible Markup Language (XML) 1.0 (Fifth Edition)』。 以下では次の項目を見ていきます:

  • 空白文字
  • 空白の扱い
  • 行末の扱い
  • 属性値の正規化

★空白文字★

XML での空白文字は以下の4つです:

Unicode 名前 Java
#x20 space ' '
#x9 tab '\t'
#xD carriage return '\r'
#xA line feed '\n'

★空白の扱い★

XML 文書中のある要素内の空白を保存したい(空白のトリミングなどを行いたくない)ときには、その要素に @xml:space 属性を付加し、属性値を "preserve" に設定します:

<pre xml:space="preserve">
  ...
</pre>

@xml:space 属性が設定されていないとき、もしくは @xml:space 属性の値が "default" の場合は、その XML 文書を受け取るアプリケーションのデフォルトの処理が行われます*2。 要は、@xml:space 属性を付加すると、HTML の <pre> 要素と同じように空白を扱うようになると言うことでいいんでしょう。

★行末の扱い★

XML 文書のパーサは解析時に

  1. #xD#xA → #xA」つまり \r\n → \n
  2. #xD → #xA」つまり \r → \n

の置き換えをしなければいけないことになっています。 したがって、行末は「#xA (\n)」だけと思って扱って構わないようです。

★属性値の正規化★

属性値は、解析時に「正規化*3」という処理を行うことになっています。 正確な記述ではありませんが、この変換は概ね以下の処理を行います*4

  1. 文字参照 (&#xA; など)、実体参照(&lt; など)を参照している文字置き換える
  2. #xD, #xA, #x9 は空白 (#x20) に置き換える
  3. 属性の型がCDATA*5 でないなら、先頭と後尾の空白を取り除き、連続する空白文字を1つの空白に置き換える

XHTML 1.0


仕様書は『XHTML〓 1.0 The Extensible HyperText Markup Language (Second Edition)』。 以下では次の項目を見ていきます:

  • 属性値での空白の扱い
  • 属性値内での改行
  • HTML と XML での空白文字

★属性値での空白の扱い★

属性値での空白の扱いは、XML でのものと同じになっています:

  • 先頭と後尾の空白を除去する
  • 1つ以上の空白文字の連なりを「単語間の空白 (inter-word space) 」に変換する

原文短いので、そのまま載っけときます:

4.7. White Space handling in attribute values
When user agents process attributes, they do so according to Section 3.3.3 of [XML]:

  • Strip leading and trailing white space.
  • Map sequences of one or more white space characters (including line breaks) to a single inter-word space.

ただし、XML ではこれらの処理を行うのは「属性の型が CDATA でないとき」となってますが、XHTML ではこれを常に行うようです。 まぁ、HTML に出てくる属性に文章 (CDATA) はなさそうなので問題はないようですが、何か一言あってもいいじゃん?

★属性値内での改行★

属性内では、改行 (line break) や空白文字の連なり (multiple white space characters) を使ってはいけないようです。 原文:

C.5. Line Breaks within Attribute Values
Avoid line breaks and multiple white space characters within attribute values. These are handled inconsistently by user agents.

★HTML と XML での空白文字★

HTML では許されている文字が、XML (XHTML) では許されていない場合があるようです。 また、空白の定義も異なっているので注意が必要。 原文:

C.15. White Space Characters in HTML vs. XML
Some characters that are legal in HTML documents, are illegal in XML document. For example, in HTML, the Formfeed character (U+000C) is treated as white space, in XHTML, due to XML's definition of characters, it is illegal.

formfeed ('\f') は、HTML では空白文字として扱われますが、XML (XHTML) では使ってはいけない文字になっています。

*1:仕様書内での「単語」とは、空白文字以外の文字の連なり (sequence) と定義されています。

*2:正直、アプリケーションはどんなマークアップXML 文書が来るか知っているはずなので、こういった指定をする必要なく空白をどのように扱うか決定できると思うんですが。 もしくは、どう扱っていいか分かるようにマークアップ(タブ名)を決めるようにすべきかと。

*3:英語では『Normalization』。 同じように「正規化」と訳される語として『Canonicalization』というものがありますが、この日記中で出てくるときは「正準化」と記します。 一般には使われていませんが、物理学関連の人には分かって貰えるハズ。

*4:仕様書では、属性値の文字列の構築方法が書かれてますが、ここではそうはしていません。

*5:CDATA とは文字データ(Character Data)のこと。 単語やその列挙ではなく文章(テキスト)。