Une classe très puissante qui transforme un fichier XML en objet actionscript. L'avantage de cette classe est qu'elle permet de contrôler la transformation du XML.
Bientôt disponible ! ;)
L'idée de base :
Après avoir utilisé la classe XML2Object de Sephiroth, que je trouvais géniale et fort pratique, à force d'utilisation, j'ai voulu aller plus loin.
Quelques problématiques me sont apparues :
Par exemple, on ne peut pas créer d'instances d'une classe précise, juste de bêtes objets...
Autre chose, impossible d'apeller une fonction après la création de l'objet.
Et puis le code me semblait un peu lourd pour un simple parseur xml... pas normal tous ces tests, ces reconstructions d'arrays partout...
Après avoir testé le codage en dur dans la classe avec des switch pas très jolis, je me suis dit "allez, on va se faire sa propre classe XMLtoObject".
Evidemment impossible de s'en tenir à un truc basique. Obligé de faire encore mieux que l'objectif de départ. J'y ai donc ajouté la finesse du xpath (l'implémentation de xfactorstudio).
Voici l'idée :
On définit des filtres correspondants à chaque noeud.
Le filtre du noeud permet de dire ce qu'on va faire avec tout ce XML.
Dans ce filtre, on peut appeler des expressions xpath ou xml à tout moment.
De plus, les valeurs parsées sont typées automatiquement : chaine, nombre, booléen, m�me les arrays ! cool nan ?
Explication :
Et boum ! On parse le xml et magie, magie, on a un bel objet créé suivant ces quelques règles.
Assez de blabla, voici comment on créée une règle :
(il ne devrait pas être trop compliqué de créer les règles depuis.... un xml ! en appelant la fonction justement ;)
XMLtoObject_instance = new XMLtoObject();
XMLtoObject_instance.bindings.AclassName = new XMLbind(
{
name:"xml:attributes.name",
type:"xpath:name()",
attributes:{
excludeList:[
"aprop",
"notthisprop",
"pliznotthisone"
//etc...
]
},
properties:{
childrenLength:"xpath:count(./*)"
anotherProp:"xml:attributes.aprop"
//etc...
},
constructorParams:[
"xpath:name()",
"xml:attributes._x",
"blabla",
4
//etc...
],
functionBefore:{
scope:this,
func:this.test,
args:[
"xpath:name()",
"xml:attributes.name",
"xml:attributes._x",
"blabla",
4
//etc...
]
},
functionAfter:{
scope:this,
func:this.test,
args:[
"xpath:name()",
"xml:attributes.name",
"xml:attributes._x",
"blabla",
4
//etc...
]
}
}
);
myObject = XMLtoObject_instance.returnObj(XMLdata);
donc, si on avait le noeud suivant :
<AclassName
name="imthenode"
aprop="avalue"
notthisprop="hello"
pliznotthisone="youhou"
iwanthis="yes"
andthis="8">
<Achild/>
<Achild/>
<Achild/>
<AsingleChild/>
</AclassName>
Cela créerait un objet comme suit :
imthenode = { // de type AclassName !
iwanthis:"yes", // les props qu'on a filtré
andthis:8,
childrenLength:3, // les props qu'on a ajouté
anotherProp:"avalue",
AsingleChild:Object // un objet enfant seul
Achild:[Object, Object, Object],
/* les objets enfants sont
dans un array s'il y'en a
plusieurs du même nom
(le nom défini dans name
pour le noeud Achild ) */
}
Un peu la flemme de taper un code plus long qui serait peut être plus parlant, peut être plus tard ;)