Accueil > > > TUTORIEL COMPLET XML
TUTORIEL COMPLET XML
Information sur la source
Description
Voici un tutoriel complet sur l'utilisation du xml dans flash.
Source
- Pour expliquer comment utiliser le xml dans flash, je vais prendre un exemple concret.
- Nous apprendre a exploiter un fichier xml en prenant comme exemple un systeme de news fictif.
- Nous ne realiserons que l'exploitation des donnée, pas le systeme lui meme.
- L'affichage se fera via la fonction trace().
-
- Je part sur le principe que vous connaissez les fonctions de base du langage, en particulier les boucles et les bases de la POO.
-
- Voici donc le fichier sur lequel nous allons travailler;
-
- <?xml version='1.0' encoding='UTF-8' ?>
- <main>
-
- <news>
- <title value="titre de la news" />
- <texte>
- <![CDATA[ blablabla ]]>
- </texte>
- <links>
- <link url="http://www.allboard.net" text="Allboard Network" />
- <link url="http://www.blackwizzard.com" text="BlackWizzard NetWork" />
- <link url="http://www.underground-fr.com" text="Underground-fr" />
- </links>
- </news>
-
- <news>
- <title value="une 2eme news" />
- <texte>
- <![CDATA[ texte de la 2eme news ]]>
- </texte>
- <links>
- <link url="http://www.v-network.info" text="Allboard Network" />
- </links>
- </news>
-
- </main>
-
- Comme vous pouvez le voir, nous devons specifier un header. si il n'y en a pas, flash va quand meme le charger, mais ce header permet de preciser l'encodage.
-
- <?xml version='1.0' encoding='UTF-8' ?>
-
- les info sont entre <?xml et ?>
- version='1.0' ne changera pas puisque seul la version 1.0 existe pour l'instant ;)
-
- encoding='UTF-8' determine l'encodage du fichier.
- UTF-8 est le plus utilisé, mais il existe une multitude d'encodages possibles.
- UTF-8 est le codage 'europeen'. Il est celui utilsé dans les pays utilisant notre alphabet.
- Il existes d'autres encodage tel que windows-1252, ISO-8859-1, UTF-16 ...
-
- Apres le header, nous voyons que les Balises sont mis entre une paire de balise <main></main> que l'on appele balises "root".
- quelque soit le document xml, Tout le document doit etre encadré ce cette pair de balise.
- Le nom de cette paire balise n'as pas d'importance.
-
- Il y a 2 types de balises;
- Celles, comme en HTML qui se composent en paire <nom></nom> et celles uniques, qui sont de type <nom />
- Chaque type de balise ouvrante px accueillir des parametres, exemple, <nom parametre="valeur"></nom> ou <nom parametre="valeur" />.
- Les balises uniques ne servent uniquement a accueillir des parametres.
- Pour fournir un texte complet, mettez le entre une paire de balises, mais attention! si votre texte se compose de code html, les balises html seront considérés comme des balises xml, ce qui entrainera souvent une erreur.
- Pour eviter cela, Vous pouvez placer votre texte entre les pseudo-balises <!CDATA![ et ]]>.
- exemple:
- <nom>
- Voici un texte en gars: <br>
- <b>blablabla</b>
- </nom>
- Si vous faittes comme cela, les balises html vont etre considérées comme du xml, et la syntaxe n'etant pas correct, en particulier pour le <br>, le fichier va retourner une erreur. C'est alors qu'intervient le CDATA:
- <nom>
- <![CDATA[
- Voici un texte en gars: <br>
- <b>blablabla</b>
- ]]>
- </nom>
- Tout ce qui se trouve dans la balise CDATA ne sera pas interpreté.
-
-
- Maintenant que vous possedez les bases syntaxiques du XML, nous allons commencer le code action-script.
-
- Pour exploiter du xml, nous devons declarer un nouvel objet XML:
- myXML = new XML();
-
- Nous voulons que les espaces et sauts de lignes ne soient pas interpretés (ce qui est preferable, sinon ça fout le bordel), pour cela, nous disposont de la propriété ignoreWhite:
- myXML.ignoreWhite = true;
-
- Nous allons maintenant charger le fichier:
- myXML.load("fichier.xml");
-
- Le fichier pouvant mettre plusieurs secondes a se charger en focntion de sa taille et de la conenction, nous allons faire intervenir la fonction onLoad() qui executera son code des que le xml est chargé. Cette fonction recoit un argument de type booleen (1 ou 0; true ou false) qui correpond a l'etat de chargement; true(1) = le document est chargé, false(0) = le document n'est pas chargé, probablement indisponible ou en erreur:
- myXML.onLoad = function(flag) {
- if (flag) { // si flag = true
- // reste du code.
- }
- }
-
- Maintenant que nous savons composer et charger un document XML, il faut l'analyser.
- Pour cela, Nous allons parcourir les "branches" du fichier, qui comme tt le monde a du le remarquer se compose comme une arborescence.
- Pour cela, nous allons utiliser une boucle while(), bien qu'il soit aussi possible de passer par un for().
- Voici l'arborescence sommaire du fichier :
-
- +main
- -+news
- ----title (value)
- ----texte [cdata]
- ---+links
- ------link 1 (url, text)
- ------link 2 (url, text)
- ------link 3 (url, text)
- -+news
- ----title (value)
- ----texte [cdata]
- ---+links
- ------link 1 (url, text)
-
- j'espere qu'il est assez clair pour tt le monde.
-
- Afin de parcourir le fichier, nous disposons de 2 fonctions principales:
- xml.firstChild et xml.childNodes[x].
- xml.firstChild retourne la premiere "branche" du noeud "xml".
- xml.childNodes[x] retourne le noeud "x" du noeud "xml", sinon il retourne "undefined" si la valeur le noeud "x" n'est pas trouvé.
- xml.firstChild equivaut donc à xml.childNodes[0].
-
- quand le fichier xml est chargé, notre objet XML "myXML" prend comme valeur le contenu du fichier xml.
- Vous pouvez vous en rendre compte en effectuant un trace(myXML);
- Donc, afin d'isoler les sections de news, nous pouvons faire trace(myXML.firstChild); qui va nous retourner uniquement les zones de news.
-
- Etant donnée que le nombre de news est dynamique, nous allons les afficher une par une, sans savoir a l'avance combien il y en a.
- Pour cela, nous allons utiliser notre boucle while, xml.childNodes[x] et xml.firstChild.
- (tout le code qui suis devra se placer a la place de "// reste du code.", dans la fonction onLoad()).
-
- //initialisation
- i=0; // on initialise le compteur.
- x = myXML.firstChild; // on se place sur le noeud des news.
- while (x.childNodes[i] != undefined) { // tant qu'il y a des news...
- trace(x.childNodes[i]); // on affiche le noeud de news trouvé.
- i++; // on incremente le compteur.
- }
- trace(i+" news trouvées"); // on affiche le nombre de news trouvé, c'est pas utile
- // pour ce tutoriel, mais c'est un plus ;)
-
- Voila!
- Nous avons commencé a parcourir le fichier!
- Si vous avez compris le bout de code ci-dessus, vous avez tout compris du xml, ou presque.
-
- Mais afin de faire un tutoriel complet, je vais aller jusqu'au bout de cette exploration du fichier.
- Nous avons donc su afficher chaque noeud de news.
- Nous allons donc explorer chaque news!
- Pour cela, nous devons nous servir d'une nouvelle fonction: xml.attributes
- Pour comprendre l'utilité de cette focntion, il faut voir les specificités du xml; En effet, nous avons 2 facons pour stocker du texte:
- - entre une paire de balise: <nom>texte</nom>
- - dans une balise: <nom attr="texte" />
- Pour acceder au premier type (la paire de balise), un simple firstChild suffit.
- Par contre, pour acceder a la balise elle meme, nous devons utiliser noeud_xml.attributes.nom_attribut
- Exemple :
- Pour <link url="http://www.allboard.net" text="Allboard Network" />
- Pour acceder a la valeur de "url", nous allons faire noeud_xml.attributes.url
- et pour acceder a la valeur de "texte" noeud_xml.attributes.text
-
- Voici donc le code complet qui permet d'explorer le fichier xml.
- Vous disposez maintenant de toutes les notions necéssaires pour comprendre ce code.
-
- i = 0;
- x = myXML.firstChild;
- while (x.childNodes[i] != undefined) {
- trace(""); // ligne vide
- trace("--- NEWS "+(i+1)+" ---"); // le (i+1) permet d'afficher "NEWS 1" et non pas "NEWS 0",
- // mais c'est juste une question esthetique.
- trace("titre:\t"+x.childNodes[i].childNodes[0].attributes.value); // le titre, avec le fameux "attributes"!
- trace("texte:\t"+x.childNodes[i].childNodes[1].firstChild); // le texte, via un simple firstChild.
- trace("liens:"); // ha! là on ne sais pas combien il y a de liens par news! ça devient interessant!
- j = 0; // on initialise j.
- while (x.childNodes[i].childNodes[2].childNodes[j] != undefined) { // tant qu'il y a des liens...
- trace("\t --- LIEN "+(j+1)+" ---"); // on affiche le numero de lien...
- trace("\t lien:\t"+x.childNodes[i].childNodes[2].childNodes[j].attributes.url); // ...son url,
- trace("\t texte:\t"+x.childNodes[i].childNodes[2].childNodes[j].attributes.text); // son texte...
- j++; // on incremente le compteur j.
- }
- i++;
- }
- trace(""); // ligne vide, purement esthetique.
- trace(i+" news trouvées");
-
- Et voila!
- Vous pouvez desormais vous servir du xml, qui est si pratique avec flash!
- Un conseil, avant de coder, regardez bien la structure du xml, si elle est complexe, faites le shema simplifié comme on a fait, et distinguez bien les elements statiques (titre, texte toujours au meme nombre et à la meme place) des elements dynamiques (souvent a la meme place, mais rarement au meme nombre).
-
- Amusez vous bien!
-
-
- Je resume le code complet ::
-
- myXML = new XML();
- myXML.ignoreWhite = true;
- myXML.load("file.xml");
- myXML.onLoad = function(flag) {
- if (flag) {
- i = 0;
- x = myXML.firstChild;
- while (x.childNodes[i] != undefined) {
- trace("");
- trace("--- NEWS "+(i+1)+" ---");
- trace("titre:\t"+x.childNodes[i].childNodes[0].attributes.value);
- trace("texte:\t"+x.childNodes[i].childNodes[1].firstChild);
- trace("liens:");
- j = 0;
- while (x.childNodes[i].childNodes[2].childNodes[j] != undefined) {
- trace("\t --- LIEN "+(j+1)+" ---");
- trace("\t lien:\t"+x.childNodes[i].childNodes[2].childNodes[j].attributes.url);
- trace("\t texte:\t"+x.childNodes[i].childNodes[2].childNodes[j].attributes.text);
- j++;
- }
- i++;
- }
- trace("");
- trace(i+" news trouvées");
- }
- };
-
-
- Ce tutoriel à été ecrit par BlackWizzard pour Flashkod.
- Diffusion autorisé a la seul condition de laisser mon pseudo en signature.
Pour expliquer comment utiliser le xml dans flash, je vais prendre un exemple concret.
Nous apprendre a exploiter un fichier xml en prenant comme exemple un systeme de news fictif.
Nous ne realiserons que l'exploitation des donnée, pas le systeme lui meme.
L'affichage se fera via la fonction trace().
Je part sur le principe que vous connaissez les fonctions de base du langage, en particulier les boucles et les bases de la POO.
Voici donc le fichier sur lequel nous allons travailler;
<?xml version='1.0' encoding='UTF-8' ?>
<main>
<news>
<title value="titre de la news" />
<texte>
<![CDATA[ blablabla ]]>
</texte>
<links>
<link url="http://www.allboard.net" text="Allboard Network" />
<link url="http://www.blackwizzard.com" text="BlackWizzard NetWork" />
<link url="http://www.underground-fr.com" text="Underground-fr" />
</links>
</news>
<news>
<title value="une 2eme news" />
<texte>
<![CDATA[ texte de la 2eme news ]]>
</texte>
<links>
<link url="http://www.v-network.info" text="Allboard Network" />
</links>
</news>
</main>
Comme vous pouvez le voir, nous devons specifier un header. si il n'y en a pas, flash va quand meme le charger, mais ce header permet de preciser l'encodage.
<?xml version='1.0' encoding='UTF-8' ?>
les info sont entre <?xml et ?>
version='1.0' ne changera pas puisque seul la version 1.0 existe pour l'instant ;)
encoding='UTF-8' determine l'encodage du fichier.
UTF-8 est le plus utilisé, mais il existe une multitude d'encodages possibles.
UTF-8 est le codage 'europeen'. Il est celui utilsé dans les pays utilisant notre alphabet.
Il existes d'autres encodage tel que windows-1252, ISO-8859-1, UTF-16 ...
Apres le header, nous voyons que les Balises sont mis entre une paire de balise <main></main> que l'on appele balises "root".
quelque soit le document xml, Tout le document doit etre encadré ce cette pair de balise.
Le nom de cette paire balise n'as pas d'importance.
Il y a 2 types de balises;
Celles, comme en HTML qui se composent en paire <nom></nom> et celles uniques, qui sont de type <nom />
Chaque type de balise ouvrante px accueillir des parametres, exemple, <nom parametre="valeur"></nom> ou <nom parametre="valeur" />.
Les balises uniques ne servent uniquement a accueillir des parametres.
Pour fournir un texte complet, mettez le entre une paire de balises, mais attention! si votre texte se compose de code html, les balises html seront considérés comme des balises xml, ce qui entrainera souvent une erreur.
Pour eviter cela, Vous pouvez placer votre texte entre les pseudo-balises <!CDATA![ et ]]>.
exemple:
<nom>
Voici un texte en gars: <br>
<b>blablabla</b>
</nom>
Si vous faittes comme cela, les balises html vont etre considérées comme du xml, et la syntaxe n'etant pas correct, en particulier pour le <br>, le fichier va retourner une erreur. C'est alors qu'intervient le CDATA:
<nom>
<![CDATA[
Voici un texte en gars: <br>
<b>blablabla</b>
]]>
</nom>
Tout ce qui se trouve dans la balise CDATA ne sera pas interpreté.
Maintenant que vous possedez les bases syntaxiques du XML, nous allons commencer le code action-script.
Pour exploiter du xml, nous devons declarer un nouvel objet XML:
myXML = new XML();
Nous voulons que les espaces et sauts de lignes ne soient pas interpretés (ce qui est preferable, sinon ça fout le bordel), pour cela, nous disposont de la propriété ignoreWhite:
myXML.ignoreWhite = true;
Nous allons maintenant charger le fichier:
myXML.load("fichier.xml");
Le fichier pouvant mettre plusieurs secondes a se charger en focntion de sa taille et de la conenction, nous allons faire intervenir la fonction onLoad() qui executera son code des que le xml est chargé. Cette fonction recoit un argument de type booleen (1 ou 0; true ou false) qui correpond a l'etat de chargement; true(1) = le document est chargé, false(0) = le document n'est pas chargé, probablement indisponible ou en erreur:
myXML.onLoad = function(flag) {
if (flag) { // si flag = true
// reste du code.
}
}
Maintenant que nous savons composer et charger un document XML, il faut l'analyser.
Pour cela, Nous allons parcourir les "branches" du fichier, qui comme tt le monde a du le remarquer se compose comme une arborescence.
Pour cela, nous allons utiliser une boucle while(), bien qu'il soit aussi possible de passer par un for().
Voici l'arborescence sommaire du fichier :
+main
-+news
----title (value)
----texte [cdata]
---+links
------link 1 (url, text)
------link 2 (url, text)
------link 3 (url, text)
-+news
----title (value)
----texte [cdata]
---+links
------link 1 (url, text)
j'espere qu'il est assez clair pour tt le monde.
Afin de parcourir le fichier, nous disposons de 2 fonctions principales:
xml.firstChild et xml.childNodes[x].
xml.firstChild retourne la premiere "branche" du noeud "xml".
xml.childNodes[x] retourne le noeud "x" du noeud "xml", sinon il retourne "undefined" si la valeur le noeud "x" n'est pas trouvé.
xml.firstChild equivaut donc à xml.childNodes[0].
quand le fichier xml est chargé, notre objet XML "myXML" prend comme valeur le contenu du fichier xml.
Vous pouvez vous en rendre compte en effectuant un trace(myXML);
Donc, afin d'isoler les sections de news, nous pouvons faire trace(myXML.firstChild); qui va nous retourner uniquement les zones de news.
Etant donnée que le nombre de news est dynamique, nous allons les afficher une par une, sans savoir a l'avance combien il y en a.
Pour cela, nous allons utiliser notre boucle while, xml.childNodes[x] et xml.firstChild.
(tout le code qui suis devra se placer a la place de "// reste du code.", dans la fonction onLoad()).
//initialisation
i=0; // on initialise le compteur.
x = myXML.firstChild; // on se place sur le noeud des news.
while (x.childNodes[i] != undefined) { // tant qu'il y a des news...
trace(x.childNodes[i]); // on affiche le noeud de news trouvé.
i++; // on incremente le compteur.
}
trace(i+" news trouvées"); // on affiche le nombre de news trouvé, c'est pas utile
// pour ce tutoriel, mais c'est un plus ;)
Voila!
Nous avons commencé a parcourir le fichier!
Si vous avez compris le bout de code ci-dessus, vous avez tout compris du xml, ou presque.
Mais afin de faire un tutoriel complet, je vais aller jusqu'au bout de cette exploration du fichier.
Nous avons donc su afficher chaque noeud de news.
Nous allons donc explorer chaque news!
Pour cela, nous devons nous servir d'une nouvelle fonction: xml.attributes
Pour comprendre l'utilité de cette focntion, il faut voir les specificités du xml; En effet, nous avons 2 facons pour stocker du texte:
- entre une paire de balise: <nom>texte</nom>
- dans une balise: <nom attr="texte" />
Pour acceder au premier type (la paire de balise), un simple firstChild suffit.
Par contre, pour acceder a la balise elle meme, nous devons utiliser noeud_xml.attributes.nom_attribut
Exemple :
Pour <link url="http://www.allboard.net" text="Allboard Network" />
Pour acceder a la valeur de "url", nous allons faire noeud_xml.attributes.url
et pour acceder a la valeur de "texte" noeud_xml.attributes.text
Voici donc le code complet qui permet d'explorer le fichier xml.
Vous disposez maintenant de toutes les notions necéssaires pour comprendre ce code.
i = 0;
x = myXML.firstChild;
while (x.childNodes[i] != undefined) {
trace(""); // ligne vide
trace("--- NEWS "+(i+1)+" ---"); // le (i+1) permet d'afficher "NEWS 1" et non pas "NEWS 0",
// mais c'est juste une question esthetique.
trace("titre:\t"+x.childNodes[i].childNodes[0].attributes.value); // le titre, avec le fameux "attributes"!
trace("texte:\t"+x.childNodes[i].childNodes[1].firstChild); // le texte, via un simple firstChild.
trace("liens:"); // ha! là on ne sais pas combien il y a de liens par news! ça devient interessant!
j = 0; // on initialise j.
while (x.childNodes[i].childNodes[2].childNodes[j] != undefined) { // tant qu'il y a des liens...
trace("\t --- LIEN "+(j+1)+" ---"); // on affiche le numero de lien...
trace("\t lien:\t"+x.childNodes[i].childNodes[2].childNodes[j].attributes.url); // ...son url,
trace("\t texte:\t"+x.childNodes[i].childNodes[2].childNodes[j].attributes.text); // son texte...
j++; // on incremente le compteur j.
}
i++;
}
trace(""); // ligne vide, purement esthetique.
trace(i+" news trouvées");
Et voila!
Vous pouvez desormais vous servir du xml, qui est si pratique avec flash!
Un conseil, avant de coder, regardez bien la structure du xml, si elle est complexe, faites le shema simplifié comme on a fait, et distinguez bien les elements statiques (titre, texte toujours au meme nombre et à la meme place) des elements dynamiques (souvent a la meme place, mais rarement au meme nombre).
Amusez vous bien!
Je resume le code complet ::
myXML = new XML();
myXML.ignoreWhite = true;
myXML.load("file.xml");
myXML.onLoad = function(flag) {
if (flag) {
i = 0;
x = myXML.firstChild;
while (x.childNodes[i] != undefined) {
trace("");
trace("--- NEWS "+(i+1)+" ---");
trace("titre:\t"+x.childNodes[i].childNodes[0].attributes.value);
trace("texte:\t"+x.childNodes[i].childNodes[1].firstChild);
trace("liens:");
j = 0;
while (x.childNodes[i].childNodes[2].childNodes[j] != undefined) {
trace("\t --- LIEN "+(j+1)+" ---");
trace("\t lien:\t"+x.childNodes[i].childNodes[2].childNodes[j].attributes.url);
trace("\t texte:\t"+x.childNodes[i].childNodes[2].childNodes[j].attributes.text);
j++;
}
i++;
}
trace("");
trace(i+" news trouvées");
}
};
Ce tutoriel à été ecrit par BlackWizzard pour Flashkod.
Diffusion autorisé a la seul condition de laisser mon pseudo en signature.
Sources du même auteur
Commentaires et avis
|
Derniers Blogs
TECHDAYS PARIS 2012 : COMMENT SHAREPOINT A SAUVé MES TECHDAYSTECHDAYS PARIS 2012 : COMMENT SHAREPOINT A SAUVé MES TECHDAYS par ROMELARD Fabrice
Speakers : Lionel Limozin et Alain Marty La session commence par une découverte de SharePoint à travers la mise en place d'un environnement SharePoint pour la gestion des Sessions animées par BeWise. Le besoin est très ba...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice PERSPECTIVE 3.0 POUR SILVERLIGHT 5.0PERSPECTIVE 3.0 POUR SILVERLIGHT 5.0 par odewit
Je viens de publier la version 3.0 de Perspective pour Silverlight, qui regroupe un portage sous Silverlight 5.0 des fonctionnalités de Perspective 2.0, le framework 3D de haut-niveau introduit récemment et de nouveaux exemples de code. En voici la li...
Cliquez pour lire la suite de l'article par odewit TECHDAYS PARIS 2012 : TOP 10 DES BEST PRACTICES POUR SQL SERVERTECHDAYS PARIS 2012 : TOP 10 DES BEST PRACTICES POUR SQL SERVER par ROMELARD Fabrice
Speaker : Nadia Ben El Kadi Configuration machine La session commence par la toute première question à se poser lors de la mise en place d'environnement SQL Server, la configuration des machines : Type de mac...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2012 : KINECT + OFFICE 365 UN BON GESTE POUR VOTRE SITECHDAYS PARIS 2012 : KINECT + OFFICE 365 UN BON GESTE POUR VOTRE SI par ROMELARD Fabrice
Speakers : Fabrice Barbin, Samuel Blanchard, Julien Lo Presti Titre Prometteur et attractif invitant à voir comment lier le composant ludique Kinect dans le cadre d'une structure IT classique, notamment au travers de la plat...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2012 : PLEINIèRE DU PREMIER JOURTECHDAYS PARIS 2012 : PLEINIèRE DU PREMIER JOUR par ROMELARD Fabrice
KeyNotes du premier jour pour les développeurs. La session est principalement axée sur une des principales directions prise par Microsoft à travers tous ses nouveaux produits : Cloud privé ou public (Solution Azure) ...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning COLLECTOR PLUS (3.00B)COLLECTOR PLUS (3.00B)COLLECTOR PLUS version 3.00B est un logiciel utilisant une base de données alimentée par :
- L... Cliquez pour télécharger COLLECTOR PLUS PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO LettresFaciles 2011 (8.0.0.1)LETTRESFACILES 2011 (8.0.0.1)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011
|