XML Article
軽量XMLパーサ活用のススメ
シンプルな読み書き処理に特化した、軽く、操作性に優れたXMLパーサの提案
DOMやSAXに対応したXMLパーサは、XML仕様(ないしはDOM仕様)で規定されているさまざまな記法や高度な操作を提供する。これを利用することにより、開発者はさまざまなメリットを享受することができる。しかし、アプリケーションによっては、そのような高度な機能は必要とせず、むしろ軽量であったり、扱いが容易であったりするほうが都合が良い場合もあるはずだ。そこで、本稿では、軽量かつ操作性に優れたXMLパーサを紹介する。
2005年2月14日更新
小規模アプリケーションに適した軽量XMLパーサのニーズ
XML文書をプログラムで扱う際には、まず最初に、XML文書を読み込み、それがXML仕様に準拠したものとなっているか、またどのような構造の文書であるかを解析し、そのうえで、必要な操作を行うことになる。この構文解析/字句解析を行うためのプログラムがXMLパーサ(XMLプロセッサ)である。
一般に、XMLパーサはSAXやDOMといった標準APIをベースとしている。ただし、そうしたパーサには、いくつかの欠点がある。
まず、SAXパーサの場合、イベント駆動型のAPIであるがゆえに、アプリケーションに組み込む際には、非常に煩雑な処理を記述しなければならない。また、新規にXMLファイルを生成する機能が備わっていないこともアプリケーションによっては欠点となりうる。
一方、DOMパーサであれば、パース機能に加え、XMLファイルの生成機能も利用できる。しかし、DOMパーサの場合、最初にXML文書全体を読み込み、それを基にツリー構造のモデルに従ったオブジェクトを生成するので、サイズの大きいXML文書を扱う場合に、そのために消費するメモリ量が問題になることもある。また、XML仕様に加え、DOMの膨大な仕様をフルに実装したものだと、パーサ実装のファイル・サイズが大きくなる。用途によっては、この点がネックになることもある。
もちろん、上述したことは、案件によってはまったくささいなことであり、SAX/DOMパーサによって享受できるメリットのほうを重視すべきケースも多いだろう。しかし、小規模なアプリケーションで、ごく単純な構造のXMLファイルを読み書きしたいだけな場合には、XML仕様(あるいはDOM仕様)のすべてをサポートする大がかりパーサは不要だというケースも多いはずだ。すなわち、XML文書操作のごく基本的な処理が行えて、なおかつパーサ実装のサイズが小さいことが望ましいケースである。
筆者は、まさにそのような案件に遭遇し、小規模なアプリケーション開発に適した軽量なXMLパーサを求め、インターネット上で調査を行った。その結果、米国JavaWorldのWebサイトにある、スティーブン・ブラント氏の記事『Java Tip 128:Create a Quick-and-Dirty XML Parser』に行き当たった。この記事では、XML文書をSAX方式(XML文書の先頭から解析を始め、「文書の開始」、「要素の開始」といったイベントを生成する)で読み込むことができるコンパクトなXMLパーサが紹介されている。
しかし、このXMLパーサのプログラムには、2つの欠点があった。1つは、SAXに特有のコールバック・メソッドを記述する必要があるということである。もう1つは、XMLファイルの生成機能が用意されていないということだ。
そこで、筆者は、ブラント氏が開発したSAX方式のXMLパーサ(以下、SAX型パーサ)を、XMLデータの管理/読み書きが行えるDOM方式(XML文書を読み込み、ツリー構造を表現するオブジェクトをメモリ上に構築する)のパーサ(以下、DOM型パーサ)に作り直した。
修正にあたり、筆者はこのDOM型パーサのシステム要件を以下のように設定した。
●単一のクラスとして実装する(例外クラスなどは、内部クラスとして含める)
●データは、メモリ上に保持する(クラスjava.util.Vectorに類似したメソッド群による、単純なデータ操作を実現するため)
●各要素は、再帰(recursion)をサポートする独立したオブジェクトとして格納する
●属性は、各要素オブジェクト内に個別に格納する
●単純な設定情報の格納に必要となる基本タグを提供する
以下では、SAX型パーサをDOM型パーサに変更するにあたり、カスタマイズを施した部分を中心に解説していこう。
要素を表現するクラス
まず、XML文書内の要素を表現するクラスとして、以下のクラスmyXMLを用意した。
| public class myXML implements Serializable {
// 要素の名前 String tag; // 要素のデータ(Object型か、Vector型のいずれか) Object element = null; // 要素の属性 Attribute Attribute = new Attribute(); …略… public class Attribute { private Vector attributes = new Vector(); …略… private class attribute { // 属性の名前 public String name = null; // 属性のデータ public String value = null; …略… } } …略… } |
なお、このクラスmyXML自体が、XMLパーサのメインのクラスとなる。
さて、myXMLオブジェクトには、対応する要素のタグ、属性情報、およびデータ(要素の内容/属性の値)が格納される。要素が持つデータは、Object型か、Vector型のいずれかの型をとることにした。
データをVector型で格納すれば、アプリケーションからデータを操作する際に、Vectorオブジェクトを操作するのと同様のメソッドを使用することができる。クラスmyXMLでは、add、find、contains、remove、isEmpty、getといったクラスVectorの基本的なメソッドに類似したメソッドを実装している。ここでは、各メソッドについての説明は割愛するが、サンプル・コードをダウンロードのうえ、ご確認いただきたい※1。
※1 サンプル・コードは、米国JavaWorldのWebサイトからダウンロードすることができる。









