XMLの空白文字とエスケープの注意点|タブや改行はどう扱う?

Web

「XMLでデータを作ったのに、開いたら思ったように表示されない」
「空白や改行を入れたのに、なぜか無視されてしまう」

こんな経験はありませんか?

XMLでは空白文字(ホワイトスペース)の扱いに独特なルールがあります。また、空白自体はエスケープする必要はありませんが、誤解しやすいポイントも多いです。

この記事では、XMLにおける空白文字の扱い方や注意点、そして関連するエスケープについてわかりやすく解説します。

スポンサーリンク

XMLにおける空白文字とは?

空白文字(ホワイトスペース)の種類

XMLでいう「空白文字」は以下のような文字を指します。

種類具体例Unicode説明
スペース(半角空白)U+0020一般的な空白文字
タブ\tU+0009インデントでよく使われる
改行(LF)\nU+000AUnix系の改行文字
改行(CR)\rU+000D古いMac系の改行文字
改行(CRLF)\r\nU+000D + U+000AWindows系の改行文字

これらはデータの中にも使えますし、XMLファイルのインデントとしても普通に使われます。

XMLにおける空白文字の基本的な扱い

XMLでは、これらの空白文字は特別な処理を必要とせず、そのまま文字として扱われます。

<message>こんにちは 世界</message>

このように、スペースを含む文字列もそのまま記述できます。

空白文字は基本的にエスケープ不要

文字としてそのまま使える

多くの初心者の方が混乱するポイントですが、XMLでは空白文字をエスケープする必要はありません。

実例で確認

<name>やまだ たろう</name>
<address>東京都 渋谷区 1-2-3</address>

このようにスペースを入れても、そのままデータとして正しく扱われます。

タブや改行も同様

タブや改行も文字列内にあれば、通常はそのまま扱われます。

<poem>
    春の夜や
    桜散りゆく
    月明かり
</poem>

JSONのように \n を使って改行をエスケープする必要はありません。XMLはテキストベースのフォーマットなので、ファイル上の改行そのものが改行として扱われます。

複数行テキストの例

<description>これは
複数行の
テキストです。

改行も含まれています。</description>

このように書けば、中身はそのまま改行を含むテキストデータになります。

空白文字でハマりやすいポイント

インデントは見た目だけで処理には影響しない

XMLファイルを見やすくするためのインデントは、実際のデータ内容には関係ありません。

インデントの例

<item>
    <name>りんご</name>
    <price>100</price>
</item>

このインデント用のスペースやタブは、XMLパーサが無視するので、あくまで見た目を整えるためのものです。

インデントありとなしは同じ意味

<!-- インデントあり -->
<item>
    <name>りんご</name>
</item>

<!-- インデントなし -->
<item><name>りんご</name></item>

どちらも同じデータとして扱われます。

要素内容の前後の空白は削除される場合がある

要素の内容の前後にある空白は、XMLパーサによって削除される場合があります。

<name>   やまだたろう   </name>

この場合、前後の空白が削除されて "やまだたろう" として処理される可能性があります。

属性値での空白の扱い

属性値の中では、複数の連続する空白が1つにまとめられることがあります。

<note text="abc    def" />

処理系によっては "abc def" として扱われる場合があります。

属性値での改行とタブ

属性値内の改行やタブは、スペースに変換されることが多いです。

<!-- このような属性値は -->
<element attr="line1
line2" />

<!-- このように処理される場合がある -->
<element attr="line1 line2" />

xml:space属性で空白を厳密に保持

xml:space=”preserve”の使い方

どうしても空白や改行をそのまま保持したいときは、xml:space="preserve" を使います。

<message xml:space="preserve">
    改行も
    タブも    スペースも
    そのまま保持されます
</message>

これによりXMLパーサが余計な空白を削除せずに、そのまま扱ってくれます。

xml:space=”default”との違い

<!-- デフォルトの動作 -->
<text xml:space="default">
    前後の空白は
    削除される可能性があります
</text>

<!-- 空白を保持 -->
<text xml:space="preserve">
    前後の空白も
    そのまま保持されます
</text>

継承される性質

xml:space 属性は子要素に継承されます。

<parent xml:space="preserve">
    <child>この子要素でも空白が保持されます</child>
    <child xml:space="default">この子要素では通常の処理</child>
</parent>

エスケープが必要なのは特殊文字

空白文字はエスケープ不要

繰り返しになりますが、空白文字(スペース・タブ・改行)はエスケープする必要がありません。

XMLでエスケープが必要な文字

XMLでエスケープが必要なのは以下の特殊文字です。

文字エスケープ後使用場面
<&lt;タグの開始記号と区別するため
>&gt;タグの終了記号と区別するため
&&amp;エスケープ文字と区別するため
"&quot;属性値の引用符と区別するため
'&apos;属性値の引用符と区別するため

エスケープの実例

<!-- 正しいエスケープ -->
<formula>5 &lt; 10 &amp;&amp; 10 &gt; 3</formula>
<message title="&quot;Hello World&quot;">内容</message>

<!-- 間違った例(エラーになる) -->
<formula>5 < 10 && 10 > 3</formula>

XMLの空白処理をプログラムで確認

Pythonでの確認例

import xml.etree.ElementTree as ET

# XMLデータ
xml_data = '''
<root>
    <text1>   前後に空白   </text1>
    <text2 xml:space="preserve">   前後に空白   </text2>
</root>
'''

root = ET.fromstring(xml_data)
print(f"通常: '{root.find('text1').text}'")
print(f"preserve: '{root.find('text2').text}'")

この例では、xml:space="preserve" の有無による違いを確認できます。

実際の処理結果

多くのXMLパーサでは、以下のような結果になります:

  • text1: "前後に空白" (前後の空白が削除)
  • text2: " 前後に空白 " (空白が保持)

XMLファイル作成時の注意点

エディタの設定に注意

XMLファイルを作成するとき、エディタの設定によって意図しない空白が入ることがあります。

よくある問題

  • 行末の見えない空白文字
  • タブとスペースの混在
  • 改行コードの違い(LF、CR、CRLF)

検証方法

作成したXMLファイルが正しく処理されるか、実際にパーサで読み込んで確認することをおすすめします。

<!-- 検証用の簡単な例 -->
<test>
    <item>テスト項目</item>
    <space-test xml:space="preserve">   空白テスト   </space-test>
</test>

まとめ

今回は「XMLの空白文字とエスケープ」について解説しました。

重要なポイント:

  • 空白(スペース・タブ・改行)はそのまま使える。エスケープは不要
  • XMLパーサはインデント用の空白を無視する
  • 要素内容の前後の空白は削除される場合がある
  • 空白を正確に保持したいときは xml:space="preserve" を使う
  • エスケープが必要なのは <>&"' の5文字

これらのルールを理解しておけば、XMLで空白文字による予期しないトラブルを防げます。特に、データの前後に意図しない空白が入ってしまう問題や、改行が期待通りに処理されない問題を避けることができるでしょう。

コメント

タイトルとURLをコピーしました