(約)40行で出来るXML→JSONパース

2009 年 6 月 5 日

ちょっとやってて感動したので書いてみる。

XHRで取ってきたレスポンスのXMLをパースしてJSONに変換するものです。

結構仰々しいのかなぁ・・・と思いつつ書いてたらあっさりできた。時間にして20分くらい?

折角なのでちょっコードをさらしてみます。

function XMLToJSON(ajax){

if (ajax.responseXML != null)var xmlDoc = ajax.responseXML;
else {
if (window.ActiveXObject) {
var xmlDoc = new ActiveXObject(’Microsoft.XMLDOM’);
xmlDoc.async = false;
xmlDoc.loadXML(ajax.responseText);
}
else if (window.DOMParser) var xmlDoc =  new DOMParser().parseFromString(ajax.responseText, “application/xml”);
else return;
}
var xml = xmlDoc.documentElement;
var loopParse = function(obj)
{
var res = {}, cacheTag = {};
var ob = {}, att = obj.attributes;
if (att != null && att.length != 0) {
for (var a = 0, lenA = att.length; a < lenA; a++) {
ob[att[a].nodeName.toLowerCase()] = att[a].nodeValue;
}
res._attr = ob;
}

for (var i = 0, len = obj.childNodes.length; i < len; i++)
{
var ch = obj.childNodes[i];
if (ch.nodeType == 3)
{
if (ch.nodeValue.replace(/[\s|\t|\n]/g, ”) == ” || ch.nodeValue == null)continue;
else return ch.nodeValue;
}
else if (ch.nodeType == 1)
{
(ch.tagName in cacheTag) ? cacheTag[ch.tagName].push(arguments.callee(ch)) : cacheTag[ch.tagName] = [arguments.callee(ch)];
}
}
for (var p in cacheTag)(cacheTag[p].constructor == Array && cacheTag[p].length == 1) ? res[p] = cacheTag[p][0] : res[p] = cacheTag[p];
return res;
}
return loopParse(xmlDoc);

}

うーん、これだと本当に40行かどうか分からない・・・。

「マジかよ?本当に40行かよ?」という人はテキストエディタとかにコピーして適宜改行を消してみてください。多分大丈夫です。

でわ、何やってるかというと、まず引数にXHRオブジェクトを渡します。

で、最初にresponseXMLがあるかチェック、あればそれを使用。なければ、ActiveXObject(IE)、DOMParserを使ってresponseTextからXMLをパース。これならIEのローカル環境でも試せます。

で、肝なのがローカルで宣言しているloopParse関数。

Rootから子要素をリスト化し、ElementNodeかTextNodeかを判定、空でなければリストに追加、同じタグ名は配列にしまう、って感じです。属性もオブジェクトのしまってますね。あとはその子要素について同じ関数を再帰呼び出ししてパースしまくり、です。

おそらくひどいくらいにloopParse関数が呼ばれるので、出来るだけ軽くしてみました。単純なXMLファイルなら数~数十msでパースすると思います(Firefox3)。XMLベースならIEもそれなりの動作が期待できるので、処理を分ける必要性が少なくていいですね。

というわけで、XMLをJSONにするのに大きなライブラリは必要なかった、という結論に。XHRでとってこれればOK。

イベントの設定にもマナーを

2009 年 5 月 29 日

某会社のCMみたいですが(笑)、人の作ったライブラリを見てると、時々イベントの設定をしっぱなしのものがあります。

PCでも電源を入れて、使い終えたら電源を切りますよね?それと同じで、イベントの設定をしたら、用を終えたらきちんとイベント解除しないといけないんじゃないかなぁ・・・なんて思います。

例えば、よくあるドラッグドロップ。

あんまり考えずに作ると、ドラッグするかどうかをフラグで管理する人がいますね(flag = trueならドラッグする、とか)。

これも一つの方法でしょうが、例えばmousedownでflag = true、mouseupでflag = falseにするとかします。

で、mousemoveではif (flag == false)return;とかやってるわけですが、これでも動くでしょう。

でも実は、マウスを動かす度にmousemoveのリスナは呼ばれてるんですよ!

ただ直ぐにreturnするだけですが、マウスを動かす度にリスナが呼ばれるとしたら、それはもう数百、数千回の単位で呼ばれ、悲しくも直ぐにreturn。

何も起こらないのでいいかもしれませんが、関数呼び出しには結構メモリを使います。mousemoveなんてかなりヤバイ。

なので、mousedownでmousemoveイベント設定、mouseupでリスナ解除、という風にちゃんとマナーを付けたいですね。

フラグ管理は万一の為のセーフガードとして私は使ってます。

attachEventとaddEventListenerの分岐も面倒くさがらずに・・・。

と書いておきながら、自分でも耳が痛いですね(笑)当たり前のようで、あまりやってない話でした。

第三回勉強会、無事終了しました

2009 年 5 月 25 日

去る2009年5月23日(土)、無事勉強会を開催することが出来ました。

定員20名にも関わらず、多数のお申し込みを頂き、定員満了での開催となりました!

CSSは基礎の基礎、幾分かマニアックな内容も含めてセレクタからのスタート。本当にさわりくらいしか出来ませんでしたが、良い反響を頂けて感激しております。

PHPは制御構文(ループ)をやりました。内容的には「ああ、プログラミングなんだなぁ」という内容でした。

配列とかは挫折しそうな部分なだけに、しっかりとできたかちょっとだけ心配です・・・

ともあれ、またも時間が足りなくて出来なかったところ、途中で終わってしまった所を近いうちにリベンジしたいですね!

参加頂いた皆様、ありがとうございました!!

JavaScriptでMD5を作りたいけど・・・

2009 年 5 月 7 日

PHPとかで結構使うMD5。暗号化した値の生成に用いるんですが、当然JavaScriptにはMD5関数なんてありませんよね。

となると自作しないといけないんですが、これがかなり手間がかかります。

私はアルゴリズムとか深い所まで理解していないダメな方なので^^;

といってもいずれは組み込まないといけないですね。参った。ビット演算とか微妙な理解度なんですよね~。

これだとただのつぶやきになってしまうので、とってもすごい方が作成したMD5化ライブラリを勝手に紹介しておきます。

http://www.webtoolkit.info/javascript-md5.html

とか、

http://www.kanasansoft.com/weblab/2006/12/javascriptmd5.html

とか、

http://rocketeer.dip.jp/sanaki/free/javascript/freejs17.htm

とかですかね。みなさん凄い。

第三回勉強会、開催します

2009 年 4 月 30 日

前回からかなり間が空いていしまった勉強会ですが、やっと第三回の告知を行うことが出来ました。

デザイナーのためのプログラミング入門

↑詳細はコチラから

開催日は5月23日(土)、13:00~です。参加費は無料です。

今回はCSSとPHPの二本立てでお送りします。

う~ん、CSSはプログラミング言語なのか?という疑問は置いておいて、要望を頂いたのでやります。

テキストも現在作成中ですが、CSS初心者の方向けで、かつ「CSS知ってるよ」という方にもちょっと読み応えのある

内容になりそうです。若干マニアックです。

PHPは前回の続きになりますね。…といっても、また基礎に戻ってループやら関数やらをまとめようという感じです。

基礎は大事ですよね、何事も。

でも、ただ単にループとかやってもきっと退屈なので、何か趣向を凝らさねば、と。

ともあれ、無料なので5月末にちょっと時間のある方はどうぞご参加下さい。

とっても優しい講師&スタッフが、分かるまで教えます。交流会もあるので個人的な質問もあればその時にどうぞ。