1. XML への入門
今日では JSON が標準ですが、Java の世界にはレガシーコードが多く、XML に遭遇することがあります。基本を理解しておくと役に立ちます。 XML (eXtensible Markup Language) は、構造化データの保存と交換のためのテキスト形式です。設定ファイル、アプリケーション間のデータ交換、データ保存、さらにはオブジェクトのシリアライズにもよく使われます。
XML ドキュメント構造の基本要素:
タグ(要素):
すべては < と > の間にあります。各タグには開始タグ(<tag>)と終了タグ(</tag>)があり、自己終了(<tag/>)させることもできます。
属性:
タグ内の追加パラメータ。
例: <user name="Vasya" age="25"/>
テキストノード:
タグの間にあるテキスト。
例: <greeting>こんにちは、世界!</greeting>
簡単な XML ドキュメントの例
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user name="Vasya" age="25">こんにちは!</user>
<user name="Katya" age="30"/>
</users>
ここでは:
- <users> はルート要素です。
- <user> は属性 name と age を持つ要素で、最初のユーザーにはテキスト内容があります。
2. 重要な概念
プロローグ:
ファイル先頭の行で XML のバージョンとエンコーディングを指定します。
例: <?xml version="1.0" encoding="UTF-8"?>
要素:
XML の基本的な構成要素です。
例: <book>...</book>
属性:
開始タグ内のパラメータです。
例: <book title="Java" author="Ivanov"/>
コメント:
HTML と同様、<!-- ... --> の間に記述します。
例: <!-- これはコメントです -->
CDATA セクション:
<、& などの文字を含む、XML として解釈させたくないテキストを挿入できます。
例:
<script><![CDATA[
if (a < b && b > 0) { ... }
]]></script>
3. なぜ XML に名前空間が必要か
問題: 名前の衝突
大きな XML ドキュメントでは、同じタグ名でも意味が異なる場合がよくあります。たとえば、HTML の一部としての <table> と、ビジネスロジック(たとえばデータベース)の一部としての <table> があるとします。どのタグが何を表すのか、どう区別すればよいでしょうか?
名前空間なし:
<root>
<table>
<row>...</row>
</table>
<table>
<column>...</column>
</table>
</root>
ここではどの <table> が何に対応するのか分かりません。
解決: 名前空間
名前空間(Namespace) は、要素や属性に「印」を付けて名前の衝突を避け、異なるタグの意味を明確に区別するための仕組みです。
- 各名前空間は一意の URI(見た目はリンクでも、単なる識別子)です。
- 名前空間が異なれば、同じ名前でも別の要素・属性として扱われます。
利点:
- 異なる標準やスキーマ間で名前の衝突が起きません。
- 異なるソースのデータを 1 つの文書に統合できます。
- 各タグがどの「語彙」に属するかが明確になります。
4. 名前空間の使い方: 宣言と適用
名前空間を宣言する方法
要素の開始タグに特別な属性 xmlns(XML Namespace)を書きます:
- プレフィックスなし: xmlns="URI" — 以降の入れ子になった要素に既定の名前空間を宣言します。
- プレフィックスあり: xmlns:prefix="URI" — タグで使用する短い名前(プレフィックス)つきの名前空間を宣言します。
名前空間の宣言と利用の例
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="http://www.w3schools.com/furniture">
<h:table>
<h:tr>
<h:td>セル 1</h:td>
<h:td>セル 2</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>テーブル</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>
ここでは:
- xmlns:h="..." — HTML テーブル用のプレフィックス h を宣言しています。
- xmlns:f="..." — 家具用のプレフィックス f を宣言しています。
- <h:table> と <f:table> は、名前が同じでも別の要素になります。
名前空間の使い方
- 宣言: ルート要素や任意の要素で xmlns:prefix="URI" を指定します。
- 適用: 要素名や属性名の前にプレフィックスとコロンを付けます: <prefix:element>...</prefix:element>
既定の名前空間
xmlns="URI" のように宣言すると、プレフィックスのない要素はすべてその名前空間に属します。
<books xmlns="http://example.com/books">
<book>...</book>
</books>
5. 実践: 複数の名前空間を持つ簡単な XML ドキュメントの作成
HTML 用と家具用の 2 つの名前空間を使った XML ドキュメントの例を作成してみましょう。
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="http://www.w3schools.com/furniture">
<h:table>
<h:tr>
<h:td>セル 1</h:td>
<h:td>セル 2</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>テーブル</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>
ここで行っていること:
- ルート要素で 2 つの名前空間 h と f を宣言しています。
- h: プレフィックスの付いたすべての要素は HTML テーブルに関するものです。
- f: プレフィックスの付いたすべての要素は家具に関するものです。
6. 典型的なミス
ミス 1: プレフィックスの宣言忘れ
<root>
<h:table>...</h:table>
</root>
結果: XML パーサーがエラーを出します: The prefix 'h' for element 'h:table' is not bound.
ミス 2: 名前空間なしで同じ名前を使用
<root>
<table>...</table>
<table>...</table>
</root>
結果: どの <table> が何に対応するのか区別できません。
ミス 3: プレフィックスの誤用
<root xmlns:h="http://www.w3.org/TR/html4/">
<h:table>...</h:table>
<f:table>...</f:table> <!-- エラー: プレフィックス f が宣言されていません -->
</root>
結果: パーサーエラー: The prefix 'f' for element 'f:table' is not bound.
GO TO FULL VERSION