j'ai comme devoir de réaliser un interpréteur XML mais je n'ai aucune
idée comment m'y prendre.... je vous résume un peu le problème...
ont considère que le document XML est bien construit.
l'interpréteur doit reconnaitre la structure du document XML (10 pts)
il doit reconnaitres les noeuds de type textuel (2pts)
il doit reconnaitre les éléments vide ex: <HR/> (1 pts)
il doit reconnaitre les attributs (2 pts)
Ont doit lire le fichier XML en entré et générer un rapport en sortie.
On doit utiliser la récursivité et la POO pour gérer le fichier en
mémoire.
Le fichier en sortie doit etre sous le format suivant:
<A>
<B id="test">
<C>texte de C</C>
<D type="alpha"/>
<B/>
<A/>
Ont doit fournir le rapport suivant:
Le noeud <A> contient
Le noeud <B> contient
L'attribut « id » qui a la valeur «test»
Le noeud <C> contient
Le texte «texte de C»
Le noeud <D> contient
L'attribut «type» qui a la valeur «alpha»
Je vous demande votre aide car je n'y comprend absolument rien....
Alors que les meilleurs se mettent à leur clavier pour me venir en
aide!!!
Pas tout à fait. Ça marche pour les attributes, je crois, mais l'ordre des vertices fils est significatif. Si j'ai quelque chose du genre :
<body> <p> Du texte. <p> <table> <tr> <td>un</td> <td>deux</td> </tr> </table> <p> Encore du texte. </p> </body>
c'est important de pouvoir visiter les sous-vertices de <body> dans l'ordre qu'elles s'y trouvent, c-à-d <p><table><p>. Or, ton multimap va les renvoyer dans l'ordre <p><p><table> -- je crois que l'ordre des deux <p> n'est même pas défini.
oui, la dessus je suis d'accord. Dans mon utilisation, l'ordre n'a de l'importance que pour les sous tags de meme type. J'ai don juste une map qui me garanti que lorsque je recupere les sous tag de nom "n", j'aurais la sequence dans le meme ordre que dans le fichier. mais je perd en effet tout autre ordonencement. Mais dans mon cas je n'en ai pas besoin ;-)
Twxs
kanze@gabi-soft.fr wrote:
Pas tout à fait. Ça marche pour les attributes, je crois, mais l'ordre
des vertices fils est significatif. Si j'ai quelque chose du genre :
<body>
<p>
Du texte.
<p>
<table>
<tr>
<td>un</td>
<td>deux</td>
</tr>
</table>
<p>
Encore du texte.
</p>
</body>
c'est important de pouvoir visiter les sous-vertices de <body> dans
l'ordre qu'elles s'y trouvent, c-à-d <p><table><p>. Or, ton multimap va
les renvoyer dans l'ordre <p><p><table> -- je crois que l'ordre des deux
<p> n'est même pas défini.
oui, la dessus je suis d'accord. Dans mon utilisation, l'ordre n'a de
l'importance que pour les sous tags de meme type. J'ai don juste une map
qui me garanti que lorsque je recupere les sous tag de nom "n", j'aurais
la sequence dans le meme ordre que dans le fichier. mais je perd en
effet tout autre ordonencement. Mais dans mon cas je n'en ai pas besoin ;-)
Pas tout à fait. Ça marche pour les attributes, je crois, mais l'ordre des vertices fils est significatif. Si j'ai quelque chose du genre :
<body> <p> Du texte. <p> <table> <tr> <td>un</td> <td>deux</td> </tr> </table> <p> Encore du texte. </p> </body>
c'est important de pouvoir visiter les sous-vertices de <body> dans l'ordre qu'elles s'y trouvent, c-à-d <p><table><p>. Or, ton multimap va les renvoyer dans l'ordre <p><p><table> -- je crois que l'ordre des deux <p> n'est même pas défini.
oui, la dessus je suis d'accord. Dans mon utilisation, l'ordre n'a de l'importance que pour les sous tags de meme type. J'ai don juste une map qui me garanti que lorsque je recupere les sous tag de nom "n", j'aurais la sequence dans le meme ordre que dans le fichier. mais je perd en effet tout autre ordonencement. Mais dans mon cas je n'en ai pas besoin ;-)
Twxs
kanze
Twxs wrote in message news:<415b306b$0$27430$...
wrote:
Pas tout à fait. Ça marche pour les attributes, je crois, mais l'ordre des vertices fils est significatif. Si j'ai quelque chose du genre :
<body> <p> Du texte. <p> <table> <tr> <td>un</td> <td>deux</td> </tr> </table> <p> Encore du texte. </p> </body>
c'est important de pouvoir visiter les sous-vertices de <body> dans l'ordre qu'elles s'y trouvent, c-à-d <p><table><p>. Or, ton multimap va les renvoyer dans l'ordre <p><p><table> -- je crois que l'ordre des deux <p> n'est même pas défini.
oui, la dessus je suis d'accord. Dans mon utilisation, l'ordre n'a de l'importance que pour les sous tags de meme type. J'ai don juste une map qui me garanti que lorsque je recupere les sous tag de nom "n", j'aurais la sequence dans le meme ordre que dans le fichier.
D'où est-ce que tu as cette garantie. J'ai cherché dans la norme, et dans la documentation chez SGI, et je ne l'ai pas trouvée.
-- James Kanze GABI Software http://www.gabi-soft.fr Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Twxs <TwxsAATT@FreePOINT.fr> wrote in message
news:<415b306b$0$27430$626a14ce@news.free.fr>...
kanze@gabi-soft.fr wrote:
Pas tout à fait. Ça marche pour les attributes, je crois, mais
l'ordre des vertices fils est significatif. Si j'ai quelque chose du
genre :
<body>
<p>
Du texte.
<p>
<table>
<tr>
<td>un</td>
<td>deux</td>
</tr>
</table>
<p>
Encore du texte.
</p>
</body>
c'est important de pouvoir visiter les sous-vertices de <body> dans
l'ordre qu'elles s'y trouvent, c-à-d <p><table><p>. Or, ton multimap
va les renvoyer dans l'ordre <p><p><table> -- je crois que l'ordre
des deux <p> n'est même pas défini.
oui, la dessus je suis d'accord. Dans mon utilisation, l'ordre n'a de
l'importance que pour les sous tags de meme type. J'ai don juste une
map qui me garanti que lorsque je recupere les sous tag de nom "n",
j'aurais la sequence dans le meme ordre que dans le fichier.
D'où est-ce que tu as cette garantie. J'ai cherché dans la norme, et
dans la documentation chez SGI, et je ne l'ai pas trouvée.
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Pas tout à fait. Ça marche pour les attributes, je crois, mais l'ordre des vertices fils est significatif. Si j'ai quelque chose du genre :
<body> <p> Du texte. <p> <table> <tr> <td>un</td> <td>deux</td> </tr> </table> <p> Encore du texte. </p> </body>
c'est important de pouvoir visiter les sous-vertices de <body> dans l'ordre qu'elles s'y trouvent, c-à-d <p><table><p>. Or, ton multimap va les renvoyer dans l'ordre <p><p><table> -- je crois que l'ordre des deux <p> n'est même pas défini.
oui, la dessus je suis d'accord. Dans mon utilisation, l'ordre n'a de l'importance que pour les sous tags de meme type. J'ai don juste une map qui me garanti que lorsque je recupere les sous tag de nom "n", j'aurais la sequence dans le meme ordre que dans le fichier.
D'où est-ce que tu as cette garantie. J'ai cherché dans la norme, et dans la documentation chez SGI, et je ne l'ai pas trouvée.
-- James Kanze GABI Software http://www.gabi-soft.fr Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Twxs
wrote:
D'où est-ce que tu as cette garantie. J'ai cherché dans la norme, et dans la documentation chez SGI, et je ne l'ai pas trouvée.
d'une reimplementation personnel de map que j'ai fait quand je me suis rendu compte que ce n'etait pas specifie dans la norme
kanze@gabi-soft.fr wrote:
D'où est-ce que tu as cette garantie. J'ai cherché dans la norme, et
dans la documentation chez SGI, et je ne l'ai pas trouvée.
d'une reimplementation personnel de map que j'ai fait quand je me suis
rendu compte que ce n'etait pas specifie dans la norme
D'où est-ce que tu as cette garantie. J'ai cherché dans la norme, et dans la documentation chez SGI, et je ne l'ai pas trouvée.
d'une reimplementation personnel de map que j'ai fait quand je me suis rendu compte que ce n'etait pas specifie dans la norme
Christophe Lephay
Country wrote:
j'ai comme devoir de réaliser un interpréteur XML mais je n'ai aucune idée comment m'y prendre.... je vous résume un peu le problème...
ont considère que le document XML est bien construit.
l'interpréteur doit reconnaitre la structure du document XML (10 pts) il doit reconnaitres les noeuds de type textuel (2pts) il doit reconnaitre les éléments vide ex: <HR/> (1 pts) il doit reconnaitre les attributs (2 pts)
Ont doit lire le fichier XML en entré et générer un rapport en sortie. On doit utiliser la récursivité et la POO pour gérer le fichier en mémoire. Le fichier en sortie doit etre sous le format suivant:
<A> <B id="test"> <C>texte de C</C> <D type="alpha"/> <B/> <A/>
Ont doit fournir le rapport suivant:
Le noeud <A> contient Le noeud <B> contient L'attribut « id » qui a la valeur «test» Le noeud <C> contient Le texte «texte de C» Le noeud <D> contient L'attribut «type» qui a la valeur «alpha»
Dans un interpreteur classique, il y a deux taches distinctes. La première consiste à représenter les différentes instructions de ton interpreteur, la seconde à lire une entrée et à créer les objets correspondant aux différentes instructions rencontrées (parsing). On peut interpreter (c'est le cas de le dire) ton énoncé de deux manières distinctes. La première est qu'en fait tu dois juste effectuer un parsing et générer le rapport au fur et à mesure qu'on lit le texte en entrée. La deuxième, plus complexe, consiste à générer une représentation en mémoire du texte en entrée.
La deuxième interpretation est plus complexe à mettre en oeuvre et je te conseille de le faire dans un deuxième temps seulement si, comme tu le dis, tu n'y comprends rien. La première interpretation pourrait donner un truc du genre :
class XMLInterpreter { std::string Read_Mark( std::istream& );
void XMLInterpreter::Read_A( std::istream& is ) { std::cout << "Le noeud <A> contient" << std::endl;
Read( is );
std::string end = Read_Mark( is ); if( end != "<A/>" ) std::cout << "erreur : <A/> attendu" << std::endl; }
void XMLInterpreter::Read_B( std::istream& is ) { std::cout << "Le noeud <B> contient" << std::endl;
Read( is );
std::string end = Read_Mark( is ); if( end != "<B/>" ) std::cout << "erreur : <B/> attendu" << std::endl; } ... void XMLInterpreter::Read( std::istream& is ) { std::string mark = Read_Mark( is );
if( mark == "<A>" ) Read_A( is ); else if( mark == "<B> ) Read_B( is ); ... }
La fonction Read_Mark est chargée de lire la prochaine balise dans le flux en entrée is, je la laisse à tes soins.
En gros, tu crées une fonction membre pour chaque balise chargée de lire le contenu qui lui est associé. Une fonction Read parcourt le flux en entrée et appelle la fonction correspondant à chaque balise de début et ne fait rien si une balise de fin (<A/> par exemple) est rencontrée.
Les fonctions membres spécifiques à chaque balise appelle à leur tour Read (c'est là que se trouve la récursivité), puis s'assure qu'apres cette lecture se trouve bien la balise de fin associée.
C'est extremement schématique, mais c'est juste pour te donner une direction.
Dans mon exemple, il est plus question d'un parser que d'un interpreteur. Si tu veux réellement faire un interpreteur, il te faut une hiérarchie de classe en plus :
class XML_A : public XML_Mark { XML_Mark * embedded; // pointeur sur les données contenues dans <A>...<A/> ... public: void print( std::ostream& os ) { os << "Le noeud <A> contient" << std::endl; embedded->print( os ); // on demande à l'objet incorporé de s'afficher }
};
Dans ce cas, le rôle du parser est de construire les objets appropriés au lieu d'afficher directement les types de noeuds rencontrés. Là encore, celà reste extremement schematique avec juste pour but de te donner une direction. Ton parser est chargé de construire un objet de type XML_Mark * (pointeur polymorphe), que tu peux afficher par la suite par :
XML_Mark * mark; ... mark->print( std::cout );
Chris
Country wrote:
j'ai comme devoir de réaliser un interpréteur XML mais je n'ai aucune
idée comment m'y prendre.... je vous résume un peu le problème...
ont considère que le document XML est bien construit.
l'interpréteur doit reconnaitre la structure du document XML (10 pts)
il doit reconnaitres les noeuds de type textuel (2pts)
il doit reconnaitre les éléments vide ex: <HR/> (1 pts)
il doit reconnaitre les attributs (2 pts)
Ont doit lire le fichier XML en entré et générer un rapport en sortie.
On doit utiliser la récursivité et la POO pour gérer le fichier en
mémoire.
Le fichier en sortie doit etre sous le format suivant:
<A>
<B id="test">
<C>texte de C</C>
<D type="alpha"/>
<B/>
<A/>
Ont doit fournir le rapport suivant:
Le noeud <A> contient
Le noeud <B> contient
L'attribut « id » qui a la valeur «test»
Le noeud <C> contient
Le texte «texte de C»
Le noeud <D> contient
L'attribut «type» qui a la valeur «alpha»
Dans un interpreteur classique, il y a deux taches distinctes. La première
consiste à représenter les différentes instructions de ton interpreteur, la
seconde à lire une entrée et à créer les objets correspondant aux
différentes instructions rencontrées (parsing). On peut interpreter (c'est
le cas de le dire) ton énoncé de deux manières distinctes. La première est
qu'en fait tu dois juste effectuer un parsing et générer le rapport au fur
et à mesure qu'on lit le texte en entrée. La deuxième, plus complexe,
consiste à générer une représentation en mémoire du texte en entrée.
La deuxième interpretation est plus complexe à mettre en oeuvre et je te
conseille de le faire dans un deuxième temps seulement si, comme tu le dis,
tu n'y comprends rien. La première interpretation pourrait donner un truc du
genre :
class XMLInterpreter
{
std::string Read_Mark( std::istream& );
void XMLInterpreter::Read_A( std::istream& is )
{
std::cout << "Le noeud <A> contient" << std::endl;
Read( is );
std::string end = Read_Mark( is );
if( end != "<A/>" )
std::cout << "erreur : <A/> attendu" << std::endl;
}
void XMLInterpreter::Read_B( std::istream& is )
{
std::cout << "Le noeud <B> contient" << std::endl;
Read( is );
std::string end = Read_Mark( is );
if( end != "<B/>" )
std::cout << "erreur : <B/> attendu" << std::endl;
}
...
void XMLInterpreter::Read( std::istream& is )
{
std::string mark = Read_Mark( is );
if( mark == "<A>" )
Read_A( is );
else if( mark == "<B> )
Read_B( is );
...
}
La fonction Read_Mark est chargée de lire la prochaine balise dans le flux
en entrée is, je la laisse à tes soins.
En gros, tu crées une fonction membre pour chaque balise chargée de lire le
contenu qui lui est associé. Une fonction Read parcourt le flux en entrée et
appelle la fonction correspondant à chaque balise de début et ne fait rien
si une balise de fin (<A/> par exemple) est rencontrée.
Les fonctions membres spécifiques à chaque balise appelle à leur tour Read
(c'est là que se trouve la récursivité), puis s'assure qu'apres cette
lecture se trouve bien la balise de fin associée.
C'est extremement schématique, mais c'est juste pour te donner une
direction.
Dans mon exemple, il est plus question d'un parser que d'un interpreteur. Si
tu veux réellement faire un interpreteur, il te faut une hiérarchie de
classe en plus :
class XML_A : public XML_Mark
{
XML_Mark * embedded; // pointeur sur les données contenues dans <A>...<A/>
...
public:
void print( std::ostream& os )
{
os << "Le noeud <A> contient" << std::endl;
embedded->print( os ); // on demande à l'objet incorporé de s'afficher
}
};
Dans ce cas, le rôle du parser est de construire les objets appropriés au
lieu d'afficher directement les types de noeuds rencontrés. Là encore, celà
reste extremement schematique avec juste pour but de te donner une
direction. Ton parser est chargé de construire un objet de type XML_Mark *
(pointeur polymorphe), que tu peux afficher par la suite par :
j'ai comme devoir de réaliser un interpréteur XML mais je n'ai aucune idée comment m'y prendre.... je vous résume un peu le problème...
ont considère que le document XML est bien construit.
l'interpréteur doit reconnaitre la structure du document XML (10 pts) il doit reconnaitres les noeuds de type textuel (2pts) il doit reconnaitre les éléments vide ex: <HR/> (1 pts) il doit reconnaitre les attributs (2 pts)
Ont doit lire le fichier XML en entré et générer un rapport en sortie. On doit utiliser la récursivité et la POO pour gérer le fichier en mémoire. Le fichier en sortie doit etre sous le format suivant:
<A> <B id="test"> <C>texte de C</C> <D type="alpha"/> <B/> <A/>
Ont doit fournir le rapport suivant:
Le noeud <A> contient Le noeud <B> contient L'attribut « id » qui a la valeur «test» Le noeud <C> contient Le texte «texte de C» Le noeud <D> contient L'attribut «type» qui a la valeur «alpha»
Dans un interpreteur classique, il y a deux taches distinctes. La première consiste à représenter les différentes instructions de ton interpreteur, la seconde à lire une entrée et à créer les objets correspondant aux différentes instructions rencontrées (parsing). On peut interpreter (c'est le cas de le dire) ton énoncé de deux manières distinctes. La première est qu'en fait tu dois juste effectuer un parsing et générer le rapport au fur et à mesure qu'on lit le texte en entrée. La deuxième, plus complexe, consiste à générer une représentation en mémoire du texte en entrée.
La deuxième interpretation est plus complexe à mettre en oeuvre et je te conseille de le faire dans un deuxième temps seulement si, comme tu le dis, tu n'y comprends rien. La première interpretation pourrait donner un truc du genre :
class XMLInterpreter { std::string Read_Mark( std::istream& );
void XMLInterpreter::Read_A( std::istream& is ) { std::cout << "Le noeud <A> contient" << std::endl;
Read( is );
std::string end = Read_Mark( is ); if( end != "<A/>" ) std::cout << "erreur : <A/> attendu" << std::endl; }
void XMLInterpreter::Read_B( std::istream& is ) { std::cout << "Le noeud <B> contient" << std::endl;
Read( is );
std::string end = Read_Mark( is ); if( end != "<B/>" ) std::cout << "erreur : <B/> attendu" << std::endl; } ... void XMLInterpreter::Read( std::istream& is ) { std::string mark = Read_Mark( is );
if( mark == "<A>" ) Read_A( is ); else if( mark == "<B> ) Read_B( is ); ... }
La fonction Read_Mark est chargée de lire la prochaine balise dans le flux en entrée is, je la laisse à tes soins.
En gros, tu crées une fonction membre pour chaque balise chargée de lire le contenu qui lui est associé. Une fonction Read parcourt le flux en entrée et appelle la fonction correspondant à chaque balise de début et ne fait rien si une balise de fin (<A/> par exemple) est rencontrée.
Les fonctions membres spécifiques à chaque balise appelle à leur tour Read (c'est là que se trouve la récursivité), puis s'assure qu'apres cette lecture se trouve bien la balise de fin associée.
C'est extremement schématique, mais c'est juste pour te donner une direction.
Dans mon exemple, il est plus question d'un parser que d'un interpreteur. Si tu veux réellement faire un interpreteur, il te faut une hiérarchie de classe en plus :
class XML_A : public XML_Mark { XML_Mark * embedded; // pointeur sur les données contenues dans <A>...<A/> ... public: void print( std::ostream& os ) { os << "Le noeud <A> contient" << std::endl; embedded->print( os ); // on demande à l'objet incorporé de s'afficher }
};
Dans ce cas, le rôle du parser est de construire les objets appropriés au lieu d'afficher directement les types de noeuds rencontrés. Là encore, celà reste extremement schematique avec juste pour but de te donner une direction. Ton parser est chargé de construire un objet de type XML_Mark * (pointeur polymorphe), que tu peux afficher par la suite par :