JavaScriptでSAXを実現する。

JavaScriptはDOMが標準搭載になっているけれども標準のDOMはあえて使わずにSAX(Simple API for XML)ってみる。String.replaceの仕様を利用してみるといとも簡単にSAXが実現できてしまえると思うのは僕だけだろうか?

サンプル*1

/**
 * コンストラクター プチSAX。
 * String.replaceを利用してSAXっぽいことをしてみる。
 */
function PetitSAX(){};

PetitSAX.prototype =
{
	/**
	 * 解析機
	 *
	 * @string XML文字列
	 */
	parse : function(XML){
		XML.replace(/<.+?>/g, this._process(this));
	},
	/**
	 * 以下はハンドラー
	 */
	startElement : function(name)
	{
		document.write(name,"<br />");
	},
	endElement : function(name){},
	/**
	 * 内部プロセス
	 */
	_process : function(sax)
	{
		var iap;
		var inp;

		return function(str, offset, xml)
		{
			iap = str.indexOf(" ");
			inp = str.length - 1;

			if(str.charAt(1) != '/')
			{
				if(iap >= 0) inp = iap;
				sax.startElement(str.slice(1,inp));
			}
			else
				sax.endElement(str.slice(2), inp);

			// なんか返したほうがいい?
			return '';
		}
	}
};

var XML =
	"<xml>\
	<test></test>\
	<hoge>\
	<foo></foo>\
	<bar></bar>\
	</hoge>\
	</xml>";

new PetitSAX().parse(XML);
出力

XMLの開始エレメントが出力されます。

xml
test
hoge
foo
bar

代替手段

  • 正規表現の while(/<.+?>/g.exec(XML)){ };でループ処理する。
  • indexOfで<や>を見つけてループ処理する。
  • DOMでSAXっぽく仕上げる。

ほかの構文でSAXっぽいことをする為には上記の方法でがしがしループ処理するとSAXれますけど…String.replaceを合わせてどれが一番はやいんでしょうかね。

*1:かなり適当につくっているのでSAXとは言えませんけど