JeuWeb - Crée ton jeu par navigateur
[Script JS] Traiter du XML avec JS - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Script JS] Traiter du XML avec JS (/showthread.php?tid=4006)



[Script JS] Traiter du XML avec JS - Roworll - 27-05-2009

Dans le cadre d'un développement utilisant AjaX, on s'aperçoit que beaucoup de programmeurs renvoient un contenu pré-formaté pour mettre à jour la page appelante.
Si cette méthode à l'avantage d'être simple et efficace, elle manque cependant un poil de souplesse. Les informations renvoyées doivent parfaitement s'intégrer sous peine d'avoir des erreurs ou des trucs moches.

Personnellement, adepte du XML je reste fidèle à l'idée d'utiliser ce format, y compris pour le retour lors des appels AjaX. J'y vois un avantage évident : qu'on fasse un appel classique ou asynchrone, le résultat renvoyé aura un format "universel". Plus besoin de formater les informations de retour spécifiquement pour la page appelante. On peut ainsi appeler une fonction particulière via Ajax, PHP ou tout autre méthode viable et renvoyer un résultat générique, laissant à l'appelant le soin de gérer le retour.

Les pages PHP fonctionnent alors comme des services Web, prenant en entrée une poignée de paramètres et renvoyant un contenu formaté de manière unique, exploitable via PHP, XSLT, Flash, java, python, <votre parser favori ici> et même JavaScript

Reste maintenant à savoir comment récupérer et traiter tout ça dans un environnement JS (c'est le but du topic, je vous le rapelle). C'est bien plus simple qu'il n'y parait.

Les extraits de code ci dessous se basent sur mon propre objet XMLHttpRequest (une version antique est visible ici) mais peuvent être facilement adapté à d'autres méthodes.

1) Récupérer le XML
Après un appel asynchrone, on reçoit en général une belle chaine de caractère.
En l'état, ce n'est pas du XML, juste une bête chaine. Il faut donc la transformer pour en faire un vrai objet XML avec un DOM potable.
J'utilise pour ça une fonction maison : textToXML

Code PHP :
<?php 
<script type="text/javascript">
function
textToXML(XMLText){
if (
window.ActiveXObject) {
// Code IE
var doc=new ActiveXObject("Microsoft.XMLDOM");
doc.async="false";
doc.loadXML(XMLText);
} else {
// code pour Firefox, Opera, etc.
var parser=new DOMParser();
var
doc=parser.parseFromString(XMLText,"text/xml");
}
return
doc.documentElement;
}
</
script>

Cette fonction prend en entrée une chaine de caractère avec une syntaxe XML correcte et retourne un documentElement sur lequel on peut travailler.

2) Parcourir le contenu du XML
Deux méthodes et une propriété suffisent pour cela.
getElementsByTagName, getAttribute et nodeValue.

Considérons le XML suivant renvoyé suite à un appel pour une création de login.
Code :
<xml>
    <returncode status="-1">
        <error>Votre [b]nom[/b] contient des caractères interdits</error>
        <error>Votre [b]Mot de passe[b] doit faire au moins 6 caractères</error>
    </returncode>
</xml>
Le module PHP a détecté que l'utilisateur a utilisé des caractères interdits et que son mot de passe est trop court.

Voici le code JS traitant le retour
Code PHP :
<?php 
<script type="text/javascript">
//Je récupère les données et les transforme en XML
xml=textToXML(objHTTP.responseText)
//Je récupère le noeud 'returncode'
var errNode=_xml.getElementsByTagName('returncode')[0];
//Je teste la valeur de l'attribut 'status'
if(errNode.getAttribute('status')==-1){
//Une erreur est détectée (status à -1)
var sError='';
// Je récupère la liste des noeuds 'error' à partir du noeud 'returncode' (rangé dans la variable errNode)
var errList=errNode.getElementsByTagName('error');
//Je parcours la liste des noeuds 'error'
for(x=0;x<errList.length;x++){
//bbfmt est une fonction qui transforme les tags BBCode en tags HTML
//nodevalue me permet de récupérer le contenu du noeud
sError+=bbfmt(errList[x].childNodes[0].nodeValue)+'<br />';
}
//showError esr une fonction qui affiche une fenêtre d'erreur avec le contenu passé en paramètre
showError(sError);
} else {
// Code en cas de réussite
// (affichage, rechargement, au choix...)
}
</
script>

Relativement simple, très efficace et modulable.


RE: [Script JS] Traiter du XML avec JS - Ter Rowan - 27-05-2009

y a un truc qui m'étonne : tu utilises le retour "text" que tu transformes en xml, et pas directement le retour "xml" de l'objet de httpTrucMuch

Qu'est ce qui a motivé ce choix ?


perso, j'utilise directement le retour xml mais, ayant constaté que je n'arrivais pas manipuler les attributs ( IE ne les comprenaient pas a prioiri) je suis passé en mode balise sans attribut.

Est ce pour la même raison ?


RE: [Script JS] Traiter du XML avec JS - Roworll - 27-05-2009

Citation :perso, j'utilise directement le retour xml mais, ayant constaté que je n'arrivais pas manipuler les attributs ( IE ne les comprenaient pas a prioiri) je suis passé en mode balise sans attribut.

Est ce pour la même raison ?
Exactement.

responseText fonctionne bien mieux que responseXML qui m'a, pour sa part, posé des tonnes de soucis.
Voila pourquoi je récupère le texte pour le transformer.

Procéder de cette manière causait moins de problèmes de compatibilité.


RE: [Script JS] Traiter du XML avec JS - keke - 27-05-2009

He ben merci beaucoup pour cette ressource.

Kéké


RE: [Script JS] Traiter du XML avec JS - naholyr - 28-05-2009

Tant qu'à récupérer des données structurées (ce qui est très bien, beaucoup mieux que du HTML direct on est bien d'accord) pourquoi renvoyer du XML verbeux (chaque élément a son nom répété deux fois alors qu'une suffit) au lieu du JSON ?

XML : 282 caractères
Code :
<Personnages><Personnage><Nom>Arnold</Nom><Niveau>37</Niveau><Inventaire><Arme>Epée</Arme><Bouclier>Porte</Bouclier><Or>3700</Or></Inventaire></Personnage><Personnage><Nom>Bob</Nom><Niveau>41</Niveau><Inventaire><Arme>Faux</Arme><Or>500</Or></Inventaire></Personnage></Personnages>

JSON : 147 caractères, et possibilité de n'envoyer que l'entête sans corps (encore un gain de trames)
Code :
({Personnages:[{Nom:"Arnold",Niveau:37,Inventaire:{Arme:"Epée",Bouclier:"Porte",Or:3700}},{Nom:"Bob",Niveau:41,Inventaire:{Arme:"Faux",Or:500}}]})

OK c'est moins lisible par l'humain, mais coup de bol ce n'est pas un humain qui doit le lire (en plus c'est discutable), et un gain de près de 50% sur la taille des échanges Ajax, c'est pas négligeable quand on sait à quel point ils ont tendance à vite se multiplier.
En plus avec une bonne librairie (Prototype ou JQuery par exemple) le JSON est géré d'office, aussi facilement (parfois plus) que le XML.

Y a-t-il une vraie raison qui m'échapperait, à part l'amour inconditionnel du XML ? ^^


RE: [Script JS] Traiter du XML avec JS - Holy - 29-05-2009

Personnellement je renvoie le tout direct en html dans des cas trop complexes (on a pas toujours une info bien typée, bien propre).

Pour le reste, j'avoue que je devrais être un peu plus exigeant. J'utilisais responseXML perso, mais j'ai pas encore eu l'occasion de constater de problèmes :o

Et sinon la solution en JSON est intéressante et facile à mettre en place en php en plus (json_encode()). Je penser m'y convertir d'ici peu ^^

Et ce d'autant plus que les rapports de perf par rapport à d'autres fonctions de serialisation (serialize) sont très intéressantes en lecture (dépliage): https://trac.cakephp.org/ticket/6055

Ca permet une interopérabilité intéressante Smile


RE: [Script JS] Traiter du XML avec JS - Ter Rowan - 29-05-2009

(28-05-2009, 11:28 PM)naholyr a écrit : En plus avec une bonne librairie (Prototype ou JQuery par exemple) le JSON est géré d'office, aussi facilement (parfois plus) que le XML.

Y a-t-il une vraie raison qui m'échapperait, à part l'amour inconditionnel du XML ? ^^

de ce que j'ai lu, lorsque je me suis décidé pour XML, c'est que certes Javascript interprète directement JSON (même pas besoin d'une librairie) mais via la fonction Eval que je me refuse à utiliser pour raison de sécurité (peut être à tord, j ai lu un truc sur eval un jour, et depuis blacklisté ^^)


RE: [Script JS] Traiter du XML avec JS - Roworll - 29-05-2009

naholyr a écrit :Y a-t-il une vraie raison qui m'échapperait, à part l'amour inconditionnel du XML ?

La raison est donnée en introduction de mon sujet. Je m'autoquote
Roworll a écrit :Personnellement, adepte du XML je reste fidèle à l'idée d'utiliser ce format, y compris pour le retour lors des appels AjaX. J'y vois un avantage évident : qu'on fasse un appel classique ou asynchrone, le résultat renvoyé aura un format "universel".
...
Les pages PHP fonctionnent alors comme des services Web, prenant en entrée une poignée de paramètres et renvoyant un contenu formaté de manière unique, exploitable via PHP, XSLT, Flash, java, python, <votre parser favori ici> et même JavaScript

En gros, l'avantage, c'est la portabilité du résultat.
Technique testée et validée. J'ai plusieurs modules PHP qui sont selon les besoins appelés par
- Ajax : le retour est manipulé en JS
- PHP : le XML est mis en page par XSLT
- Flash : Le XML initialise des données dans le module

Inutile de gérer un format différent en fonction du module appelant. Mon code PHP ne change pas d'un poil.


RE: [Script JS] Traiter du XML avec JS - naholyr - 29-05-2009

Effectivement l'interopérabilité du JSON reste entièrement à construire, tellement peu de systèmes l'accepteront en entrée que si ce besoin existe le XML s'impose.

Dans le cas contraire jetez un oeil quand-même Smile