XML to JSON

今、せっせと誰が使うかわからないJavaScriptライブラリを作成していますが、.NetのXmlSerializerに相当するクラスが欲しくなったので作成(デモ)してみました(jQuery必須)。
ソース:dq-serial.js

基本的には自前で作成したクラスのインスタンスをXMLまたはJSONへシリアライズ(または逆に復元)します。
そのため幾つか癖があります。

  1. ‘_’から始まる属性はプライベートとみなしてシリアライズの対象外とします。
  2. プライベートメンバーから’_'を省いた同一名称のメソッドがあれば、getterまたはsetterとみなします。
  3. 配列の中のプリミティブなオブジェクトは<string />で括られます

具体的には、以下の様になります。

Foo = function() {}
Foo.prototype = {
    name: "",   //これはパブリックメンバー扱い
    _text : "",  //これはプライベートメンバー扱い
    text: function(value) {
        if(!argument.length) { return this._text; }  //引数なしならgetter
        this._text = value;
    }
}

var object = new Foo();
object.name = "Hellow,";
object.text("World");

で、これをシリアル化すると以下の様になります。

<?xml version="1.0" encoding="UTF-8" ?>
<root>
<name>Hellow,</name>
<text>World</text>
</root>

で本題?のXML->JSONを実現するには [XML(文字列)→]XML(DOM) → Object [→任意のクラス(必要なら)]→JSONという段階を踏みます。
とりあえず、XML(DOM)からオブジェクトを作成するコードを示しておきます(後はデモをみてくださいorz)。

_preprocess = function (xml, to) {
    if (xml.attributes == null) {
        return to;
    }
    for (var i = 0; i < xml.attributes.length; i++) {
        var c = xml.attributes[i];
        to[c.nodeName] = $(c).text();//クロスブラウザの為にjQuery経由で参照
    }
    for (var i = 0; i < xml.childNodes.length; i++) {
        var c = xml.childNodes[i];
        if (c.nodeName == "#text") { //余分な改行を読み飛ばす
            continue;
        } else if (c.nodeName == "string") { //プリミティブな値の配列に対応
            if (!(to instanceof Array)) {
                to = [];
            }
            to.push($(c).text());
        } else if (c.childNodes.length == 1 && c.childNodes[0].nodeType != 1) {
            if (to[c.nodeName]) {
                if (!(to[c.nodeName] instanceof Array)) {
                    var tmp = to[c.nodeName]; //複数出現した段階で配列化
                    to = [];
                    to.push(tmp);
                }
                to.push($(c).text());
            } else {
                if (to instanceof Array) {
                    to.push($(c).text());
                } else {
                    to[c.nodeName] = $(c).text();
                }
            }
        } else {
            if (to[c.nodeName]) {
                if (!(to[c.nodeName] instanceof Array)) {
                    var tmp = to[c.nodeName];
                    to[c.nodeName] = [];
                    to[c.nodeName].push(tmp);
                }
                var value = {};
                value = _preprocess(c, value);
                to[c.nodeName].push(value);
            } else {
                to[c.nodeName] = {};
                to[c.nodeName] = _preprocess(c, to[c.nodeName]);
            }
        }
    }
    return to;
}

M. K. の紹介

IT屋さんです。プログラミングが大好きで今はJavascriptがお気に入りです。
カテゴリー: dq, JavaScript, ゲーム作成   タグ:   この投稿のパーマリンク