XML

XMLファイルとは

JSON の、冗長な先祖。企業間や行政のデータ交換は今もこれが背骨です。

XML とは何か

XML はプレーンテキスト形式です。どのエディターでも開けます。 プログラム間のデータ受け渡しのために使われます。

拡張子は .xml、正式名称は Extensible Markup Language です。ただしどちらも、そのファイルが中に何を持てるかほどには多くを語りません。このページの残りは、その中身についての話です。

XML はどこから来たのか

W3C が 1998 年に公開しました。 仕様は XML 1.0 です。

これだけ長く読まれ続けてきた形式なら、10 年後に取り出したいものを預けても大丈夫です。

仕様は公開されています

仕様書がそのまま公開されているので、中身を推し量るのではなく文書を読んで実装できます。この形式が数多くのプログラムに載っているのはそのためであり、20 年前に書かれたファイルが今も開けるのもそのためです。ただし「仕様が公開されている」ことと「使用料が要らない」ことは別の話です。中でコーデックを包んでいる形式では、特許のライセンスは仕様書が答えていない別の問題として残ります。

捨てられるものはありません

XML ファイルは中身をそのまま保存します。保存し直しても何も変わらないので、開いて、直して、また保存する——それを何度繰り返しても劣化は積み上がりません。これが、渡すための形式ではなく作業のための形式である理由です。

コメントを書き残せます

XML ファイルにはコメントを書く方法があります。人が面倒を見るファイルと、プログラムが書き出すファイルを分けるのは、まさにこの一点です。コメントを持てない形式へ変換すると真っ先に消え、しかも誰も警告してくれません。

XML を開けるのは何か

Visual Studio CodeとoXygen XML Editorが読めますし、同じ種類のプログラムならたいてい読めます。

ファイルが開かないとき、形式が悪いことはめったにありません。たいていはプログラムのほうが形式より古いのです。もっと古い形式に変換してしまうのが確実な逃げ道で、このサイトの残りの部分はそのためにあります。

ブラウザーで開く

これは今のブラウザーならどれでも読めます。

ですからページに置くのも、メッセージに添えて送るのも、安心してできます。相手が何をインストールしているかを考える必要がありません。

作業のための形式です

XML は、開いて手を入れるために作られています。作業が続いているあいだはこの形式でファイルを持ち、完成したものが必要になるたびに、ここから書き出してください。

それ自体が形式ではなく、構造を書き留める方法

XML はそれ自体では何も記述しません。入れ子になった要素と属性で文書をマークアップするための一連の規則にすぎず、意味はその上に構築された語彙 — RSS、SVG、SOAP、XBRL、HL7、サイトマップファイル、Android のレイアウト、あらゆる Office や OpenDocument ファイルの内部構造 — から来ます。

つまり「XML ファイル」という言葉は「テキストファイル」という言葉と同じくらい、中身については何も語っていません。重要なのはどの語彙に従っているかで、それはたいていルート要素や、文書が参照するスキーマで宣言されています。

整形式と妥当は違う言葉

整形式とは、構文が正しいことを意味します。ルート要素が一つ、すべてのタグが閉じられ、要素が正しく入れ子になり、属性が引用符で囲まれ、& や < がテキストとして意図された場所ではエスケープされていること。それ以外の予約文字は、教えられるよりも実は狭い範囲でしか関係しません。> は ]]> の中でだけエスケープが必要で、引用符もそれが囲んでいる属性を終わらせてしまう場所でだけです。パーサーはこれ未満のものをすべて拒否します。XML は意図的に厳格で、HTML とは違い、エラーからの回復という仕組みがありません。

妥当とは、さらにスキーマに準拠していることを意味します。この要素はあの要素だけを含んでよい、この属性は必須、この値は日付でなければならない、といった規則です。文書は完璧に整形式でありながら、目的に対してはまったく間違っていることがあり、その違いを見つけるのが検証を行うパーサーです。規制のあるやり取りでは、その検証こそが契約であり、XML が今もその位置を保っている大きな理由です。

名前空間と、それが引き起こすバグ

名前空間は、二つの語彙を、要素名の衝突なしに組み合わせられるようにするために存在します。XHTML の table と家具カタログの table が同じ文書の中にある、といった場合です。名前空間は URI で識別されますが、これは名前であってアドレスではありません。そこから何かが取得されるわけではなく、何かに解決される必要もありません。

同時にこれは、XML の解析にまつわるバグの最大の原因でもあります。要素の名前空間を考慮せずに書かれたクエリーは、何にも一致せず、静かにそうなります。人が読めば文書は正しく見えます。パーサーが「そんな要素はない」と言い張るのに、あなたはまさにそれを目にしている場合、まず疑うべきは名前空間です。

エンコーディングの宣言は飾りではない

きちんとした XML ファイルの一行目は、バージョンと文字エンコーディングを宣言します。プレーンテキストファイルとは違い、これによってエンコーディングは推測ではなく文書の一部になります。これが XML が CSV や INI よりも国際化された文字を確実に扱える理由です。

知っておく価値のある帰結が二つあります。ある符号化を宣言しながら別の符号化で保存されたファイルは、目に見える文字化けではなく、混乱を招く解析エラーという形で壊れます。そして宣言の前にバイトオーダーマークがあると一部のパーサーが動揺するため、ここでも他の場所と同じく「BOM なしの UTF-8」が望ましい設定です。

外部エンティティは本物のセキュリティ問題

XML には省略表現、いわゆるエンティティを定義する仕組みがあり、これは伝統的に外部のリソースを指すことができました。それを解決するパーサーは、文書を提供した誰かに代わってローカルファイルを読んだり、ネットワークリクエストを発行したりします。

これが XXE 脆弱性で、何の変哲もないアップロードを通じてサーバーのファイルを露出させる、実際の情報漏えいを引き起こしてきました。関連する手口である billion laughs 攻撃は、エンティティの定義を入れ子にして、小さなファイルを数ギガバイトに展開させ、メモリーを使い果たさせます。外部エンティティが既定で解決されるかどうかは、決まっているわけではなくライブラリーごとに異なります。Java の組み込みパーサーや Python の lxml は、指定しない限り解決してしまいます。想定するのではなく、この設定を確認してください。外部から届く XML はすべて信頼できない入力です。

XML が生き残っているのは、周辺のツールのおかげ

XPath はコンパクトな表現で文書のどの部分でも指し示せ、本当に優れています。カテゴリー属性が一致する商品の中のすべての価格要素を、一行で取り出せます。XSLT は一つの XML 文書を別の XML、あるいは HTML やテキストへ、宣言的に変換します。XSD はスキーマを定義し強制します。この三つはすべて標準で、すべて成熟していて、JSON の対応物はあとから登場した分、対応が一様ではありません。

これが「XML は冗長だが有能だ」と言われるときの意味です。山かっこはその代償で、クエリー、変換、検証の仕組みこそが買われているものです。それを必要とする業界には、今もそれに完全に匹敵するものがありません。

読む、編集する、変換する

どんなテキストエディターでも開け、XML に対応したエディターを使う価値があります。セクションを折りたたみ、入力中に整形式かどうかを確認し、一行の巨大な文字列として届いた — 機械生成の XML にはよくあることです — ファイルを読みやすく整形してくれます。ブラウザーも XML を折りたたみ可能なツリーとして描画してくれ、見慣れないファイルを確認する一番早い方法です。

JSON への変換はよくあり、一方向には情報が失われます。属性には JSON に対応するものがなく、その場で考え出されたキー名が付けられ、マークアップを含む混合コンテンツには表現方法がまったくありません。データの形をした XML はきれいに変換できますが、文書の形をした XML は往復に耐えません。CSV への変換は、その文書が実際には山かっこをまとった平坦なレコードの一覧である場合にだけうまくいきます。

基本情報

XMLフォーマットの識別子と出自。
拡張子.xml
メディアタイプapplication/xml, text/xml
公開元W3C
初版1998
仕様XML 1.0

XML ファイルについてのよくある質問

XML ファイルを開くには

どんなテキストエディターでも開け、ブラウザーは折りたたみ可能なツリーとして描画してくれます。見慣れないファイルを確認する一番早い方法です。XML に対応したエディターなら、整形式かどうかのチェックも加わり、一行の長い文字列として届いたファイルも読みやすく整形できます。

整形式の XML と妥当な XML の違いは何ですか

整形式とは構文が正しいことです。ルートが一つ、すべてが閉じられ正しく入れ子になっていることです。妥当とは、さらにどの要素や属性がどこで許されるかを示すスキーマに準拠していることです。文書は整形式でありながら、目的に対しては完全に間違っていることがあります。

なぜパーサーが要素が存在しないと言うのですか

ほぼ間違いなく名前空間が原因です。要素の名前空間を考慮せずに書かれたクエリーは、何にも一致せず、静かにそうなります。人が読むと文書は正しく見えます。まずルート要素の名前空間の宣言を確認してください。

XML ファイルはセキュリティ上のリスクがありますか

あり得ます。外部エンティティの解決によって、提供された文書がローカルファイルを読んだりネットワークリクエストを発行したりできてしまいます。これが XXE 脆弱性です。入れ子になったエンティティは、小さなファイルを数ギガバイトに展開させることもできます。既定の挙動はライブラリーによって異なり、Java の組み込みパーサーや Python の lxml は指定しない限り外部エンティティを解決するため、想定せず設定を確認してください。

XML を JSON に変換できますか

データの形をした XML はきれいに変換できます。属性には JSON に対応するものがなく、その場で考え出されたキー名が付けられ、マークアップを含む混合コンテンツには表現方法がまったくないため、文書の形をした XML は往復に耐えません。

XML は時代遅れですか

いいえ。EPUB、DOCX、XLSX、SVG は内部が XML で、医療、金融、行政、出版は、妥当なメッセージとは何かを定義するスキーマ付きの XML 標準の上で動いています。ウェブ API は JSON に譲りましたが、文書や規制のあるやり取りでは今も現役です。