倭マン's BLOG

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

XML 文書のフォーマット 整理を試みる編 (3) : 空白のフォーマットについてもう少し

無視できる空白


以前は「無視できる空白 (ignorable whitespace)」を「使用できるノード」や「正規化できるノード」としても扱ってましたが、それを変更して、「無視できるノード」としてのみ扱います一覧)。

「無視できる空白」を使用するかどうかは、フォーマットではなく、別途 DTDスキーマを設定することで行うようにします(あまり具体的に考えてませんが)。

空白の型


前回、空白を幾つかの種類に分類しましたが、説明がかなり簡略化してあったので、具体例を交えて説明をしておきます。

空白の種類には以下のものがありました:

  • 境界の空白 (Boundary Whitespace)
  • 先頭と後尾の空白 (Leading and Trailing Whitespace)
  • 内部の空白 (Internal Whitespace)

以下で使うサンプルの XML 文書(インデントはスペース2文字分としています):

<root>
  <p>
    You cannot depend on your eyes when
    your imagination is out of focus.
  </p>
  <author>  MARK TWAIN  </author>
</root>

♪境界の空白 (Boundary Whitespace)♪

「境界の空白」とは、ある要素下にあり、その要素の子要素と兄弟関係 (sibling) にある空白のテキストノードです。 DTD などによる妥当性検証によって「無視できる空白 (ignorable whitespace)」として報告される可能性があるのは、この「境界の空白」のみです(たぶん)。

上記のサンプルでの「境界の空白」をアンダーバー (_) に代えると、下のようになります:

<!-- 境界の空白をアンダーバーに置き換え -->
<root>
__<p>
    You cannot depend on your eyes when
    your imagination is out of focus.
  </p>
__<author>  MARK TWAIN  </author>
</root>

この「境界の空白」を正規化すると、除去されます(下のサンプルでは、改行文字も空白文字として除去しています):

<!-- 境界の空白を正規化 -->
<root><p>
    You cannot depend on your eyes when
    your imagination is out of focus.
  </p><author>  MARK TWAIN  </author></root>

♪先頭と後尾の空白 (Leading and Trailing Whitespace)♪

「先頭と後尾の空白」とは、テキストノードの先頭と後尾にある空白のことです。 これはテキストノードの一部です。

上記のサンプルでの「先頭と後尾の空白」をアンダーバー (_) に代えると、下のようになります:

<!-- 先頭と後尾の空白をアンダーバーに置き換え -->
<root>
  <p>
____You cannot depend on your eyes when
    your imagination is out of focus.
__</p>
  <author>__MARK TWAIN__</author>
</root>

この「先頭と後尾の空白」を正規化すると、除去されます(下のサンプルでは、改行文字も空白文字として除去しています):

<!-- 先頭と後尾の空白を正規化 -->
<root>
  <p>You cannot depend on your eyes when
    your imagination is out of focus.</p>
  <author>MARK TWAIN</author>
</root>

♪内部の空白 (Internal Whitespace)♪

「内部の空白」とは、テキストノードの内容で、空白文字でない文字にはさまれた空白のことです。 これもテキストノードの一部です。

上記のサンプルでの「内部の空白」をアンダーバー (_) に代えると、下のようになります:

<!-- 内部の空白をアンダーバーに置き換え -->
<root>
  <p>
    You_cannot_depend_on_your_eyes_when
____your_imagination_is_out_of_focus.
  </p>
  <author>  MARK_TWAIN  </author>
</root>

この「内部の空白」を正規化すると、スペース1文字に置き換えられます(下のサンプルでは、改行文字も空白文字として扱っています):

<!-- 内部の空白を正規化 -->
<root>
  <p>
    You cannot depend on your eyes when your imagination is out of focus.
  </p>
  <author>  MARK TWAIN  </author>
</root>

空白の正規化とフォーマットの不変式


CDATA セクションや実体参照が使用されていると、空白の正規化をするのが悩ましいので、normalizeXxxxWhitespace() が(どれか1つでも) true を返すとき、useCData(), useEntityReferences() のどちらも false が返されなければならないと決めておきましょう:

normalizeXxxx() == true
→ useCData() == false && useEntityReferences() == false

また、逆に useCData(), useEntityReferences() が true を返すときには、normalizeXxxxWhitespace() は false を返さなければなりません:

useCData() == true || useEntityReferences() == true
→ normalizeXxxx() == false

コメントや処理命令がある場合も気になりますが、まぁいいでしょう。