XMLプログラミングのためのAPI:技術者のためのXML再入門(10)
XMLの応用分野は、単なる文書処理からデータ処理へと急速にすそ野を広げてきた。同時に、XML文書をプログラムやスクリプトで処理するのに不可欠なAPIの必要性が高まり、それにこたえるためにDOMやSAXが開発された。今回はDOMとSAXを比較検討し、次回ではDOMについてさらに詳しく解説する。
XMLデータを操作するための2つのAPI
XMLデータ(注)を操作するアプリケーションを作る場合、XMLを操作するAPI (Application Programming Interface)が標準化されていると便利なことがある。異なるXMLプロセッサ(パーサ)を使ってさまざまなアプリケーションを開発する場合でも、常に同じAPIでXMLデータを操作することができ、開発効率が向上し、プログラミングノウハウの蓄積になるからだ。そのため、XMLデータを操作するAPIとして、現在下記の2つがデファクトスタンダードとして利用されている。
●DOM (Document Object Model) ツリー・ベースのAPI
●SAX (Simple API for XML) イベント・ベースのAPI
これら2つのAPIは異なる考え方を持って開発されたもので、それぞれ特徴がある。まずは図1をご覧いただきたい。
図1のように、XMLプロセッサがXMLデータ中の要素を認識すると、DOMの場合はそれを基にDOMツリーを生成するが、SAXの場合はイベントを順次生成していく。
DOMの場合、プロセッサはXMLデータを一気に読み込んで構文解析し、メモリ上にツリーを展開する(このツリーを「DOMツリー」と呼ぶ)。DOMでは、このメモリ上に展開されたDOMツリーにアクセスしたり、要素を追加・削除することでXMLデータの構造を変更することができる。このツリー上の各要素にランダムにアクセスするためのインターフェイスを定義したものがDOMのAPIである。DOMツリーのオブジェクトは、プログラミング言語やOSにかかわらず同じ構造であるので、プログラミング言語やプラットフォームに依存しないアプリケーション開発が可能だ。とりわけ、ツリーにランダムにアクセスすることができるので、XMLデータの構造を大きく変更したい場合にはDOMが有効だ。
一方のSAXの場合、DOMのようにメモリ上にツリーを構築することなく、先頭から順にXMLデータを読み込んでいき、“要素の開始”や“要素の終わり”といったイベントを生成、その都度アプリケーションに通知する。アプリケーションはそれらのイベントを受け取ったときの処理を定義しておき、イベントを受け取ったときに呼び出されて処理を行う。SAXはイベント駆動型のAPIなので、メモリ消費量もDOMの場合と比べて少なくて済む。扱うXMLデータの容量が大きい場合にはSAXが有効だ。
DOMとSAXの考え方の大きな違いを把握したところで、それぞれの仕様の内容に触れてみよう。
DOMとは?
DOMはW3Cで標準化作業が進められ、DOM Level1が1998年10月に、Level2が2000年11月に勧告になった。DOM Level3は現在ワーキングドラフトであるが、2002年中ごろに勧告になるよう作業が進められている。DOMのLevel(レベル)とは、規格の“バージョン”を表すのではなく、“サポートする機能の程度”を表す。レベルが上がれば上がるほど高機能ということになる。しかし、高機能になればそれだけ仕様や実装が重くなるため、必要に応じたレベルを選択することが大切だ。それぞれのレベルでどんな機能がサポートされているのかをご覧いただきたい。
SAXとは?
SAXはW3Cで開発されたものではなく、開発者たちがXML-DEVメーリングリストで論議を重ねて考案したAPIだ。SAXの1.0版は1998年5月に、2.0版は2000年5月に公開された。本稿執筆時点での最新のバージョンである2.0.1版は2002年1月に公開された。ここまでで述べたように、SAXの場合はXMLプロセッサがXMLデータ中の要素を認識するたびにイベントを生成してアプリケーションに通知する。これらのイベントはアプリケーションのイベントハンドラに渡され、これを通じてXMLデータにアクセスする。イベントハンドラには、4つの基本的なインターフェイスがある(このほかのインターフェイスについては、SAXのWebサイトをご覧いただきたい)。
インターフェイス | 機能 |
---|---|
ContentHandler | XMLデータ全般に関するイベントを扱うインターフェイス |
DTDHandler | DTDに関するイベントを扱うインターフェイス。notationDecl(記法宣言)とunparsedEntityDecl(解析対象外エンティティ宣言)の2つのイベントを宣言 |
EntityResolver | エンティティ参照を解決するインターフェイス。外部エンティティ参照がないなら不要。resolveEntityイベントを宣言 |
ErrorHandler | 警告やエラー通知に関するイベントを扱うインターフェイス。warning(警告の通知)、error(回復可能エラー)、fatalError(致命的エラー)の3つのレベルのエラー・メソッドを宣言 |
表2 SAX2のインターフェイス構成 |
これら4つのインターフェイスはDefaultHandlerに組み込まれているので、 DefaultHandlerを継承すれば簡単だ。この4つのインターフェイスの中で最も基本的なものがContentHandlerであり、XMLプロセッサは以下のようなイベントをContentHandlerに渡す。
●文書の開始 (startDocument)、文書の終了 (endDocument)
●要素の開始 (startElement)、要素の終了 (endElement)
●名前空間の開始 (startPrefixMapping)、名前空間の終了 (endPrefixMapping)
●文字列 (characters)
●処理命令 (processingInstruction)
●Locatorオブジェクトの受け渡し(setDocumentLocator)
●エンティティのスキップ (skippedEntity)
もう一度、図1で見たXMLデータがSAXインターフェイスによって読み込まれる流れを考えておこう。
DOM or SAX? それともDOM and SAX?
最後にDOMとSAXを比較して検討してみよう。まず、違いをまとめた次の表をご覧いただきたい。
DOM | SAX | |
---|---|---|
モデル | ツリー(オブジェクト) | イベント |
メモリー消費 | 大 | 小 |
アクセスの方向 | ランダム・アクセスが可能 | 順次アクセス(一方向のみ) |
アクセスのタイミング | データを全部読み込んだ後 | データを読み込みながらその都度 |
処理の方式 | 対話的、選択的処理 | バッチ式処理 |
更新 | 可 | 不可 |
プログラミングの必要性 | 小 | 大 |
表3 DOMとSAXの比較 |
このように、DOMとSAXは互いに競合するものではなく、それぞれが長所と短所を併せ持っている。表3にあるような違いを把握したうえで、適宜必要に応じて使い分ける必要があるだろう。たくさんのメモリを消費するようなXMLデータを扱う場合にはSAXを、XMLデータの構造を大きく変えたいようなときはDOMを使うのがよいだろう。
次回で扱う内容
今回はDOMとSAXの特徴をとらえることができた。次回は、DOMのオブジェクトについての理解を深め、DOMの簡単な書き方について解説する。
さらにDOMとSAXを知るための関連記事
XML eXpert eXchangeフォーラムには、DOM/SAXに関する詳しい記事がいくつか掲載されている。それらを紹介しておこう。(編集局)
連載「Javaで実現するDOM/SAXプログラミング」は、タイトルどおりJavaのプログラムの中でDOMやSAXを使う方法とテクニックについて解説している。
プログラム言語として、手軽なVBScriptを使っているのが、「VBScriptでXMLプログラミング」だ。VBScriptを使うため、Windows環境ならばそのままだれでも動作を試しながら学んでいけるだろう。
Copyright © ITmedia, Inc. All Rights Reserved.