SAX は Simple API for XML の略で XML をパースする API です。もともとは Java のみの API でした。SAX は Java における XML のために最初に広く採用された API で、 そして後にいくつもの他のプログラミング言語環境に実装されました。Firefox 2 から SAX パーサが XUL アプリケーションと拡張機能で利用可能になります。より詳しい情報は SAX のホームページを参照してください。
クイックスタート
SAX パーサ機能は XML reader コンポーネントとして利用可能です。それをつくるには以下のコードを使ってください。:
var xmlReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"] .createInstance(Components.interfaces.nsISAXXMLReader);
SAX パーサを作った後、興味を持ちパース処理を発したいイベントのハンドラを設定する必要があります。全ての機能は nsISAXXMLReader インターフェースを通して利用可能です。
ハンドラを設定する
ハンドラは SAX ハンドラインターフェースをユーザが定義したオブジェクトです。それらはパーサから得たいと思う情報の種類に依ります。パース処理が始まった後、ハンドラは処理される XML コンテンツの一連のコールバックを受け取ります。以下のハンドラが利用可能です:
インターフェース | 目的 |
---|---|
nsISAXContentHandler | 文書の論理的コンテンツの通知を受け取ります(例えば、要素と属性、ホワイトスペース、処理命令)。 |
nsISAXDTDHandler | DTD に関連した基本的なイベントの通知を受け取ります。 |
nsISAXErrorHandler | 入力ストリームのエラーの通知を受け取ります。 |
nsISAXLexicalHandler | 語彙イベントの SAX2 拡張ハンドラです(例えば、コメントや CDATA ノード、DTD 宣言とエンティティ)。 |
最も一般的に使われるコンテンツのハンドラの実装例:
function print(s) { dump(s + "\n"); } xmlReader.contentHandler = { // nsISAXContentHandler startDocument: function() { print("startDocument"); }, endDocument: function() { print("endDocument"); }, startElement: function(uri, localName, qName, /*nsISAXAttributes*/ attributes) { var attrs = []; for(var i=0; i<attributes.length; i++) { attrs.push(attributes.getQName(i) + "='" + attributes.getValue(i) + "'"); } print("startElement: namespace='" + uri + "', localName='" + localName + "', qName='" + qName + "', attributes={" + attrs.join(",") + "}"); }, endElement: function(uri, localName, qName) { print("endElement: namespace='" + uri + "', localName='" + localName + "', qName='" + qName + "'"); }, characters: function(value) { print("characters: " + value); }, processingInstruction: function(target, data) { print("processingInstruction: target='" + target + "', data='" + data + "'"); }, ignorableWhitespace: function(whitespace) { // 気にしない }, startPrefixMapping: function(prefix, uri) { // 気にしない }, endPrefixMapping: function(prefix) { // 気にしない }, // nsISupports QueryInterface: function(iid) { if(!iid.equals(Components.interfaces.nsISupports) && !iid.equals(Components.interfaces.nsISAXContentHandler)) throw Components.results.NS_ERROR_NO_INTERFACE; return this; } };
パースの開始
XML Reader コンポーネントは nsIInputStream
で文字列から XML をパースすることもでき、nsIStreamListener
インターフェースを経由して非同期にパースすることもできます。以下は文字列からパースする例です:
xmlReader.parseFromString("<f:a xmlns:f='g' d='1'><BBQ/></f:a>", "text/xml");
このコールは以下のような出力になります(上の例のコンテンツハンドラを使ったと想定しています):
startDocument startElement: namespace='g', localName='a', qName='f:a', attributes={d='1'} startElement: namespace='', localName='BBQ', qName='BBQ', attributes={} endElement: namespace='', localName='BBQ', qName='BBQ' endElement: namespace='g', localName='a', qName='f:a' endDocument