XML入門 — 構文・名前空間・スキーマ・パース・セキュリティ対策まで現場で使える完全ガイド

はじめに — XMLとは何か

XML(eXtensible Markup Language)は、データの構造化・交換を目的とした汎用的なマークアップ言語です。1996年頃にW3CのXMLワーキンググループにより設計され、1998年に初期の勧告が出されました。人間と機械の双方が読み書きしやすいテキスト形式で、タグによってデータの意味や階層を表現します。

設計目的と歴史的背景

XMLはHTMLのように見た目の記述(プレゼンテーション)ではなく、データの構造と意味を表すことを目的に作られました。設計上の主なゴールは次の通りです。

  • シンプルで汎用的:幅広いアプリケーションに適用可能であること。
  • 自己記述的:タグ名でデータの意味を示せること。
  • 拡張可能:利用者やアプリケーションが独自のタグを定義できること。
  • 国際化対応:UTF-8/UTF-16などの文字エンコーディングをサポート。

これらにより、ドキュメントフォーマット、設定ファイル、Webサービス(特にSOAP)、RSSやAtomフィード、Office Open XMLやSVGなど多くの領域で採用されました。

基本構文と要素

XMLドキュメントは一般に「プロローグ(XML宣言)」「ルート要素」「子要素・属性」などから構成されます。基本的な例:

<?xml version="1.0" encoding="UTF-8"?>
<book id="b1">
  <title>XML入門</title>
  <author>山田 太郎</author>
</book>

ポイント:

  • 開始タグと終了タグで要素を囲む(空要素は<tag/>でも可)。
  • 属性は開始タグ内に name="value" 形式で記述される。
  • XMLは大文字小文字を区別する(<Book>と<book>は別物)。
  • 特殊文字(&, <, > など)はエスケープ(&amp; , &lt; , &gt;)するか、CDATAセクションで扱う。

プロローグ、エンコーディング、バージョン

XML宣言は任意ですが、エンコーディングやバージョンを明示できます。典型的な宣言は <?xml version="1.0" encoding="UTF-8"?>。XML 1.0 が最も広く使われています(W3Cの勧告は複数版ありますが、実務上は1.0が標準)。

名前空間(Namespaces)

異なるスキーマやアプリケーションで同じ要素名が衝突するのを防ぐため、XMLは名前空間をサポートします。名前空間はURIで識別され、接頭辞(prefix)を使って要素や属性に適用します。

<root xmlns:dc="http://purl.org/dc/elements/1.1/">
  <dc:title>タイトル</dc:title>
</root>

エンティティ、コメント、CDATA、処理命令

  • エンティティ参照:&entity; の形で外部または内部の定義を参照。
  • コメント:<!-- コメント -->。
  • CDATAセクション:<![CDATA[...]]> を使うと特殊文字をそのまま扱える(ただし終端シーケンスは扱えない)。
  • 処理命令(Processing Instructions):<?target data?> はアプリケーション向け命令を表現する。

Well-formed(良構文)と Valid(妥当性)

XMLには「良構文(well-formed)」と「妥当(valid)」という概念があります。良構文とは文書がXMLの基本規則(タグの整合、エスケープ、単一ルート要素など)を満たしていること。妥当であるとは、DTDやXML Schema(XSD)などで定義された構造・データ型に従っていることです。妥当性検査はアプリケーション間で契約(schema)を確認するために重要です。

スキーマ(DTD / XML Schema / RELAX NG)

XML文書の構造や型検査にはいくつかのスキーマ言語があります。

  • DTD(Document Type Definition): 古くからある形式。要素や属性の存在を定義するが、型定義は弱い。
  • XML Schema (XSD): W3Cのスキーマ言語。複雑な型定義、名前空間対応、データ型(整数や日付等)をサポート。
  • RELAX NG: より簡潔で表現力の高いスキーマ言語。XML Schemaと代替されることがある。

解析(パース)モデル:DOM, SAX, StAX

XMLを扱う際の処理モデルは主に以下の3つです。

  • DOM(Document Object Model): 文書全体をメモリ上に木構造としてロードし、ランダムアクセスや編集が可能。メモリ消費が大きくなる。
  • SAX(Simple API for XML): イベント駆動型の逐次処理。開始タグや文字データなどのイベントを受け取りながら処理するので、メモリ効率が高いがランダムアクセスは不可。
  • StAX(Streaming API for XML): プル型ストリーミングAPI。SAXとDOMの中間的な利便性(明示的に次のイベントを取得)を提供。

XSLT と XPath:変換と抽出

XSLT(Extensible Stylesheet Language Transformations)はXMLを別のXMLやHTML、テキストへ変換するための言語です。XPath はXML文書内のノードを選択するための式言語で、XSLT内でも広く使われます。これらにより、データの抽出・変換・レンダリングを宣言的に記述できます。

利用例(ユースケース)

  • データ交換フォーマット:SOAPベースのWebサービスや業務データのやり取り。
  • フィード配信:RSSやAtom。
  • 文書フォーマット:Office Open XML(.docx/.xlsx/.pptx)、OpenDocument、DocBook。
  • ベクター画像:SVG。
  • 設定ファイル:多くの古いアプリケーションがXMLベースの設定ファイルを採用。

XMLとJSONの比較

近年、データ交換ではJSONが好まれる場面が多いですが、XMLにはまだ独自の強みがあります。

  • XMLの強み:スキーマによる厳格な妥当性検査、名前空間や複雑なドキュメント構造、XSLTによる柔軟な変換、テキストベースで可読性が高い。
  • JSONの強み:軽量でシンプル、特にWeb APIやJavaScriptとの親和性が高い。構造が浅い・データ中心の用途で有利。

セキュリティ上の注意点

XML処理には特有の脆弱性が存在します。代表的なもの:

  • XXE(XML External Entity): 外部エンティティ参照を悪用してローカルファイルやリモート資源にアクセスされるリスク。対策としては外部エンティティの無効化や安全なパーサ設定が必要です。
  • XML bomb(エンティティ爆弾、Billion Laughs攻撃): エンティティ展開を利用して膨大なメモリ消費を引き起こす攻撃。エンティティ展開を制限することが重要です。
  • 署名と暗号化:XML Signature や XML Encryption により、文書の改ざん検出や機密性確保が可能だが、実装は複雑で注意が必要です。

実務上のベストプラクティス

  • パーサ設定で外部エンティティやDTDの読み込みをデフォルトで無効にする。
  • 可能ならスキーマによる妥当性検査を行い、受信データの構造を明確にする。
  • 文字エンコーディングはUTF-8を基準にし、宣言と実際のバイト列が一致しているか確認する。
  • 大きな文書はストリーミング(SAX/StAX)で処理し、メモリ不足を回避する。
  • 変換や整形が必要な場合はXSLTを適切に利用する。複雑な変換はテストとパフォーマンス評価を行う。

ツールとライブラリ(一例)

  • libxml2 / xmllint(C, 多言語バインディング)
  • Xerces(Apache, Java/C++)
  • Saxon(XSLT/XQuery の実装、商用版/オープンソース版あり)
  • lxml(Python, libxml2ベース)
  • MSXML(Windows向け)

まとめ

XMLは1990年代から広く使われてきた汎用的なマークアップ言語で、データの構造化、検証、変換に強みがあります。近年はJSONに取って代わられる場面も多いものの、スキーマによる厳格な検査、名前空間の扱い、XSLTによる変換など、特定用途では今も有効です。実装時にはパーサ設定やセキュリティ、パフォーマンスに注意することが重要です。

参考文献