xmlToObject

Voici, un embryon d’idée que j’ai eu pour créer des objets dynamiquement dans flash à partir d’un document XML. J’ai developpé une classe qui transforme des données XML préformattées en un objet Flash en respectant le datatype indiqué pour générer ses propriétés.

Je compte continuer de développer cette classe et l’utiliser par exemple pour gérer certains sites complexes sans avoir à republier les swf à chaque update et surtout plus tard m’en servir comme protocole standard pour les jeux multi-users en Xml socket d’Atomic Boarder.

Je vous fais partager mes sources ainsi que quelques explications concernant l’utilisation. Voici le code pour commencer:

/*-----------------------------------------------------------------------------------*/
// xmlToObj (08.28.2003)
//  (c) petepx aka Francis Bourre (peterphonix@usa.net)
/*-----------------------------------------------------------------------------------*/
 
_global.xmlDataUrl = "";

/*-----------------------------------------------------------------------------------*/
// XML.returnContent()
XML.prototype.returnContent = function() {
         var o = {};
         for (var x = 0; x < this.firstChild.childNodes.length; x++) {

                  o[this.firstChild.childNodes[x].nodeName] = {};
                  o[this.firstChild.childNodes[x].nodeName]["data"] = this.firstChild.childNodes[x].firstChild.nodeValue;
                  o[this.firstChild.childNodes[x].nodeName]["varType"] = this.firstChild.childNodes[x].attributes.type;
          }

         return o;
};
ASSetPropFlags(XML.prototype, "returnContent", 1);
// String.stripSpaces()
String.prototype.stripSpaces = function() {

         var s, x;
         for (x = 0; x < this.length; x++) if (this.charCodeAt(x) <> 32) s += this.charAt(x);
         return s;

};
ASSetPropFlags(String.prototype, "stripSpaces", 1);
// String.ignoreSpaces()
String.prototype.ignoreSpaces = function() {

         var s, x;
         var canDel = true;
         for (x = 0; x < this.length; x++)  {

                  if (this.charCodeAt(x) == 34 || this.charCodeAt(x) == 39) canDel = !canDel;
                  if (this.charCodeAt(x) != 32)  {

                           s += this.charAt(x);
                   } else {
                           if (!canDel) s += this.charAt(x);
                   }

          }
         return s;
};
ASSetPropFlags(String.prototype, "ignoreSpaces", 1);
/*-----------------------------------------------------------------------------------*/

// Classe xmlToObj
_global.xmlToObj = function(l) {
         this.loadData(l);
         this._listeners = new Array();
         this.addListener(this);

};
ASBroadcaster.initialize (xmlToObj.prototype);
 
// loadData()
xmlToObj.prototype.loadData = function(l) {

         var obj = this;
         var monXml = new XML();
         monXml.ignoreWhite = true;
         monXml.onLoad = function(success) { if (success) obj.makeProperties(this.returnContent()) };
         monXml.load(xmlDataUrl+l);

};
// makeProperties()
xmlToObj.prototype.makeProperties = function(o) {
         for(var x in o) {

                  switch (o[x].varType) {
                           case "number" :
                           this[x] = Number(o[x].data.stripSpaces());
                           break;
                           case "string" :
                           this[x] = o[x].data;
                           break;
                           case "array" :
                           this[x] = [];
                           var s = o[x].data.ignoreSpaces();
                           var t = s.split(",");
                           for (var y=0; y<t.length; y++) t[y].charCodeAt(0) == 34 || t[y].charCodeAt(0) == 39 ? this[x].push(t[y].substr(1,t[y].length-2)) : this[x].push(Number(t[y]));
                           break;
                           case "boolean" :
                           o[x].data.stripSpaces() == "true" || Number(o[x].data.stripSpaces()) == 1 ? this[x] = true : this[x] = false;
                           break;
                   }

          }
         this.broadcastMessage("whenObjIsLoaded");
};
// toString()
xmlToObj.prototype.toString = function() {

         var x, s;
         for (x in this) if (typeof this[x]!="function" && x != "_listeners") s +=  x+" : "+this[x]+" ["+typeof this[x]+"]n";
         return s;

};
// whenObjIsLoaded()
xmlToObj.prototype.whenObjIsLoaded = function() { trace(this) };

Et pour finir, un exemple simple d’utilisation. J’ai utilisé le core_setup.as de Robert penner pour un héritage propre, libre à vous de faire comme vous l’entendez biensûr …

// Robert Penner core_setup.as
// call superclass constructor
// usage: function Child () { this.superCon (arg1, arg2...); }
Object.prototype.superCon = function () {

         arguments.caller.prototype.__proto__.constructor.apply (this, arguments);
};
ASSetPropFlags (Object.prototype, null, 1);

 
// inherit from a superclass
// usage: Child.extend (Parent);
Function.prototype.extend = function (superclass) {

         this.prototype.__proto__ = superclass.prototype;
};
ASSetPropFlags (Function.prototype, null, 1);
/*-----------------------------------------------------------------------------------*/

 
// class News (example)
News = function(xmlUrl) { this.superCon(xmlUrl) };
News.extend(xmlToObj);

 
// main
news1 = new News ("news1.xml");
--------------------------------------------------------------------------------

Voila ! :) Questions, critiques, commentaires, idées ou suggestions sont les bienvenue :)

4 réflexions au sujet de « xmlToObject »

  1. ben c’est propre !

    peut etre rajouter un « default » dans ton switch du makepropertie pour le cas ou ca ne serait pas toi qui formaterai le xml et donc ou le datatype serait mal déclaré.

    sinon , qu’on m’arrete si je dis une connerie, mais ça s’appelle un « déserialiser » ta classe , non ?

    dans ce cas là, ça peut etre bien de pouvoir faire l’opération inverse cad de serialiser, un peu comme le WDDX de branden hall.

    d’ailleurs, on m’a dit il n’y a pas longtemps que c’etait un peu obsolete le WDDX, mais quelqu’un connait t il mieux, mise a part flash remoting ;)

  2. le WDDX n’est pas obsolete ..mais forcement quand on s’appele MM et qu’on vend du remoting et du flashcom on a tendence a vouloir minimiser des choses comme WDDX….

    en soit le principe de WDDX est excellent, seul problem c’est que cela utilise du XML pour l’echange de données, ce qui fait que cela rend un peu trop verbose ces données, maintenant on peut prendre le meme principe de serialisation/deserialisation et le faire avec un protocole plus leger que du XML, et ca donne de tres bons resultats.

  3. Marcomedia n’a aucun interêt a dénigrer le WDDX, car c’est Allaire, inventeur de ColdFusion, maintenant absorbé par Macromedia, qui a inventé ce standard …

    Le WDDX n’est plus vraiment d’actualité, dans le sens ou il est surtout destiné a représenter des données sous forme de tableaux, en décrivant chaque colonne … ce qui enlève beaucoup de souplesse par rapport au XML « standard » avec lequel on peut transmettre exactement la même chose qu’avec le WDDX.

  4. Ping : mr bricolage | tweenpix

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>