XML 整形:属性 vs 要素、インデント、名前空間の扱い

約5分

XML は構造的なデータ形式ですが、整形の自由度が高いぶん、書き方によって読みやすさが大きく変わります。本記事では XML の整形ルールと実装上の注意を整理します。

基本のインデント

要素のネストごとにインデント:

<order>
  <id>123</id>
  <items>
    <item>
      <name>Book</name>
      <price>1500</price>
    </item>
  </items>
</order>

インデント幅は 2 または 4 スペース。タブは環境依存なので避けるのが安全。

属性 vs 子要素

「データ」をどこに置くか:

属性として

<book id="123" title="SQL Basics" published="2024" />

子要素として

<book>
  <id>123</id>
  <title>SQL Basics</title>
  <published>2024</published>
</book>

選択基準:

  • 属性向き:単純な値、メタデータ、識別子、設定
  • 要素向き:複雑な構造、繰り返し、長文

「属性は値が 1 つだけ、繰り返せない、構造を持てない」という制約がある。要素は柔軟。

属性の整形

属性が多い場合は改行:

<server
  hostname="example.com"
  port="443"
  protocol="https"
  timeout="30" />

属性が少ない場合は 1 行:

<server hostname="example.com" port="443" />

自己終了タグ

中身がない要素は自己終了:

<!-- 良い -->
<br />
<img src="logo.png" />

<!-- 冗長 -->
<br></br>
<img src="logo.png"></img>

XHTML や SVG では自己終了タグ必須。XML では原則どちらも有効。

空白の扱い

XML はデフォルトで「タグ間の空白」を保持:

<name>  Alice  </name>

これは「 Alice 」(前後にスペース)として保持される。

xml:space="preserve" で明示的に保持:

<code xml:space="preserve">
  if (x > 0) {
    return x;
  }
</code>

整形ツールは原則これを尊重する。

CDATA セクション

< > & を含むテキストをそのまま入れたいとき:

<script>
  <![CDATA[
    if (a < b && b > c) {
      console.log("hello");
    }
  ]]>
</script>

整形ツールは CDATA 内をいじってはいけない。

コメント

XML のコメント:

<!-- 単一行 -->

<!--
  複数行
  コメント
-->

注意:

  • コメント内に -- を含めない(パーサーが混乱)
  • ネストできない
  • DTD 内では使えない場所がある

名前空間(Namespaces)

複数のスキーマを混在させるときに使う:

<root
  xmlns="http://example.com/default"
  xmlns:html="http://www.w3.org/1999/xhtml"
  xmlns:svg="http://www.w3.org/2000/svg">
  <html:p>段落</html:p>
  <svg:rect width="100" height="50" />
</root>

整形ツールは名前空間プレフィックスを保持・整列する必要がある。

エスケープ

XML で特殊文字をエスケープ:

文字エンティティ
<<
>>
&&
""
''

属性値内の ""(属性をシングルクォートで囲んでいる場合は '')。

XML 宣言

ファイルの先頭に:

<?xml version="1.0" encoding="UTF-8"?>

省略可能だが、UTF-8 以外を使うときは明示が必要。BOM 付き UTF-8 は推奨されない。

DOCTYPE

DTD 参照(古い XML や HTML):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

XML スキーマ(XSD)に置き換えられている。新規には DOCTYPE を使わない。

XML スキーマ vs DTD

スキーマ定義の主な選択肢:

  • XSD(XML Schema):XML 形式、型システムが豊富
  • DTD(Document Type Definition):古い、簡素、独自構文
  • RELAX NG:XSD より読みやすいとされる

新規開発は XSD が標準。

整形時の壊しやすい箇所

整形ツールが要素間のスペースを変える際の罠:

<p>Hello <b>world</b>!</p>

これを:

<p>
  Hello
  <b>world</b>
  !
</p>

と整形すると、表示時に余計なスペースが入る。混在コンテンツ(テキスト + 子要素)は整形を控えめに。

XML パーサーの違い

実装によって挙動が違う:

  • DOM パーサー:全文をメモリに読み込む(小〜中規模)
  • SAX パーサー:イベント駆動、ストリーム処理(大規模)
  • StAX:プル型のストリーム処理

設定ファイルなど小規模ファイルは DOM、大量データは SAX/StAX が向く。

XML vs JSON vs YAML

<user>
  <name>Alice</name>
  <age>30</age>
</user>
{
	"name": "Alice",
	"age": 30
}
name: Alice
age: 30
  • XML:構造化文書、DOM 操作、レガシーシステム
  • JSON:API、Web、シンプル
  • YAML:設定ファイル、人が書く

新規 API は JSON が主流。XML は SOAP、Office 文書、SVG、Atom など健在。

整形ツール

  • xmllint(libxml2):xmllint --format file.xml
  • prettier-plugin-xml:Prettier の XML プラグイン
  • xmlstarlet:XML 操作と整形
  • vscode の拡張:「XML Tools」など

CI で整形チェックを入れると、PR の差分がきれいになる。

まとめ

  • インデント幅は 2 か 4、タブは避ける
  • 単純値は属性、構造は要素
  • 自己終了タグで冗長性を減らす
  • CDATA とコメントは整形ツールがいじってはいけない
  • 名前空間プレフィックスを保持する

XML の整形・検証には、本サイトの XML フォーマッタが使えます。