XMLtoObject + Xpath

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 :

  • Déjà, on va dire où trouver les 2 infos de base pour créer l'objet :
    • le nom de l'objet à créer (par exemple l'attribut nom du noeud)
    • le type de l'objet à créer (par exemple le nom du noeud lui-même)
  • Ensuite, on va dire quels attributs vont être associés à l'objet et donc transformées en propriétés de l'objet.
    • on peut tous les prendre bien sûr
    • on peut donner une liste d'attributs
    • on peut donner une liste d'attributs à exclure
  • On peut ajouter d'autres propriétés ex-nihilo
    • n'importe quelle expression xpath ou xml ou sur l'objet lui-même peut être envoyé comme propriété
  • On peut envoyer aussi n'importe quel expression au contructeur de l'objet
  • On définit des fonctions à appeler avant et/ou après la construction de l'objet
    • on donne le scope (qui peut être l'objet créé)
    • on donne la fonction à appeler
    • et bien sûr les arguments... Là encore, on peut envoyer des expressions xpath ou xml...

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 ;)