連載 XMLツールでプログラミング(3)
SAXによるXML文書の操作
DOMとSAXは、XML文書を操作するもっともポピュラーなAPIだ。前回紹介したDOMはDOMツリーを柔軟に操作可能な一方で、SAXは大規模なXML文書を高速に処理できる特長がある。目的に合わせてこの2つを使い分けるべきだが、今回はそのSAXについて解説する。
赤木伸
日本オラクル株式会社
2000/10/5
前回はXML ParserのDOM APIを利用して下記の「Book.xml」から特定の要素の内容を取り出す方法について説明した。今回はXML文書を操作するためのもうひとつのAPIであるSAXについて説明する。
SAXでは、DOMのようにXML文書をまるごとメモリに読み込んだあと処理するのではなく、XML文書の先頭から一行ずつ順番に処理をして行く。そのため、どんなに大きなXML文書を処理するときでも、メモリの使用量はそれほど負担にならず、処理も一般に高速だという利点がある。今回も下記の「Book.xml」をサンプルにして、前回のDOMによるプログラムと同じ結果を得るプログラムを紹介しよう。
Book.xml<?xml version="1.0" encoding="Shift_JIS"
?> |
SAX(Simple API for XML)を使う |
SAXでは、要素の開始などのイベントが起こるたびに決まったメソッドが呼ばれるので、そのメソッドを実装することによって、目的の処理を行う。例えば、パース(解析)し始めて、要素の開始というイベントが起きると、startElement()というメソッドが呼ばれる。そのメソッドに、処理したい内容を記述するわけだ。
例として、先ほどの「Book.xml」をSAX Parserで解析したとき、どのようなイベントが起きるかを以下に示す。
SetDocumentLocator |
ほとんどのイベントは“StartElement”と“EndElement”であり、しかも読み込んだXML文書のエレメントの順番にイベントが発生していることが分かるだろう。
では、このイベントをふまえて、先ほどDOMを利用した例とまったく同じ結果を得る、SAXを利用したプログラムの例を見てみる。
SAXを利用したプログラム(抜粋) public class BookBySAX extends HandlerBase { } public void endElement(String name) throws SAXException |
例によって、上記のリストも必要な部分以外は省略してある。リストの全体は、BookBySAX.javaを参照してほしい。
- まず、DOMのときと同じように、SAX Parserをインスタンス化する。ただし、SAXの場合はパース(解析)する前に、いくつかやっておくことがある。SAXでは、イベントのカテゴリごとにインターフェースが用意されているので、そのうち必要なものだけをイベントハンドラとしてSAX
Parserに登録する必要がある。このインターフェイス(イベントハンドラ)には、DTDのイベントハンドラであるDTDHandlerなどといったものがあるが、今回のサンプルで必要なのは、XML文書のイベントハンドラであるDocumentHandlerとエラーのイベントハンドラであるErrorHandlerの2つである。そこで、それぞれsetDocumentHandler()とsetErrorHandler()メソッドを用いてSAX
Parserに登録している。また、HandlerBaseというクラスを継承しているのがわかるが、このクラスは一通りのイベントハンドラのデフォルトの処理(基本的になにもしていない)を実装している。よって、このクラスを継承することで、必要なインタフェースの必要なメソッドだけをオーバーライドすれば済むようになっている。
- イベントハンドラの登録の後に、いよいよparse()メソッドを用いてパース(解析)する。このメソッドの中でイベントが起こるたびに、イベントハンドラが呼ばれるわけである。
次に、イベントハンドラとして定義されているメソッドをオーバーライドしていこう。
- setDocumentLocator()メソッドのLocatorオブジェクトは、現在パースしているソース内の位置(何行目の何文字目)を取得するためのものである。ここでLocatorオブジェクトを保存することによって、エラーなどが出たときに、そのエラーの発生したソースの位置を取得できる。ここでは、「locator」という名のインスタンス変数に保存している。
- XML文書が解析され最初に呼ばれるのが、startDocument()メソッドである。ここでは、各要素を保存するためにスタックを生成している。実は、このサンプルの場合はわざわざスタックを使う必要はないのだが、今後の応用を考慮してスタックを使用している。
- endDocument()は、一通りXML文書の解析が終わるタイミングで呼ばれる。今回は、特になにもしていない。
- 次のstartElement()は、新しい要素が見つかるたびに呼ばれる。まず、スタックに要素名をプッシュ(追加)する。次に要素名が「アイテム」であれば、「アイテム」要素の「id」属性の値を「bookid」インスタンス変数に保存しておく。
- ある要素が終了したときに呼ばれるのが、endElement()メソッドである。ここでは、スタックの一番上が最新の要素になるように、終わった要素名をスタックから取り出している。また、要素名が「アイテム」のときは、「bookid」をクリアする。
- characters()は、タグ以外の文字列が見つかるたびに呼ばれる、要素の内容の文字列を返すメソッドである。ここでは、保存しておいた「id」属性の値が指定の値と同値のときだけ、要素ごとに要素の内容を取り出している。それぞれの要素の判別はスタックの一番上にある要素名と比較して行っている。
- 最後にエラーを扱うErrorHandlerインターフェースのメソッドをオーバーライドする。error()とfatalError()は、それぞれW3CのXML 1.0の仕様で定義されている「Error」と「Fatal Error」が発生したときに呼ばれるメソッドであり、warning()は、そのどちらでもない場合に呼ばれる。warning()では、処理を中断させる必要はないので、「throw e」が抜けている(上記のリストではこの部分は省略されている。詳細はBookBySAX.java)。
このコードを実行した場合も、以下のようにDOMのサンプルと同様の結果が得られる。
F:\Oracle\JDeveloper 3.1.1\java1.2\jre\bin>java BookBySAX |
今回のように、XML文書を一度たどれば済んでしまうような処理の場合は、ツリー構造をメモリ上に作成する必要のない高パフォーマンスのSAXを使うことによって、メモリの使用量をあまり気にする必要もなく、サイズの大きいXML文書を扱うことができる。ちなみに、オラクルのDOM Parserはメモリ上にDOMツリーを作成する際に、内部的にこのSAX Parserを利用している。
DOMの場合は、XML文書がツリー構造としてメモリ上に保存されているので、それに対してトップダウンに処理をするために、自分がどの位置のノードを操作しているのかが把握しやすい。一方、SAXの場合は、現在どの位置を処理しているのかをつねに考えて、頭の中で把握していないと処理を書くことができない。ゆえに、いささかSAXのプログラムのほうが複雑に見えるのではないだろうか。
最後に、オラクルのXML Parserはさまざまな仕様をサポートしているが、そのサポートする仕様とそのバージョンを以下にまとめておく。実装するときの参考にしてほしい。
■Oracle XML Parserが対応している仕様
- W3CのXML1.0勧告に準拠
- W3CのDOM Level1 1.0勧告に準拠
- SAX1.0に準拠
- W3CのNamespace in XML勧告に準拠
- W3CのXSLT1.0勧告に準拠
- W3CのXPath1.0勧告
Index | |
連載 XMLツールでプログラミング | |
(1)Javaで利用するXML開発ツール Oracle XML Developer's Kit(XDK)の紹介 |
|
(2)DOMによるXML文書の操作 DOM APIを使ったプログラムの基礎 |
|
(3)
SAXによるXML文書の操作 SAX APIを使ったXML文書操作の基礎と実践 |
|
(4)
Javaで文書作成クラスを生成する DTDを元に、XML文書を作成するJavaクラスを作る |
|
(5)
OracleからXML文書を出力する データベースへの問い合わせ結果をXML文書にする |
- QAフレームワーク:仕様ガイドラインが勧告に昇格 (2005/10/21)
データベースの急速なXML対応に後押しされてか、9月に入って「XQuery」や「XPath」に関係したドラフトが一気に11本も更新された - XML勧告を記述するXMLspecとは何か (2005/10/12)
「XML 1.0勧告」はXMLspec DTDで記述され、XSLTによって生成されている。これはXMLが本当に役立っている具体的な証である - 文字符号化方式にまつわるジレンマ (2005/9/13)
文字符号化方式(UTF-8、シフトJISなど)を自動検出するには、ニワトリと卵の関係にあるジレンマを解消する仕組みが必要となる - XMLキー管理仕様(XKMS 2.0)が勧告に昇格 (2005/8/16)
セキュリティ関連のXML仕様に進展あり。また、日本発の新しいXMLソフトウェアアーキテクチャ「xfy technology」の詳細も紹介する
|
|