OVH Cloud OVH Cloud

interpréteur xml

14 réponses
Avatar
ladycompaq
Bonjour à tous,

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!!!

Merci d'avance
Johanne

4 réponses

1 2
Avatar
Twxs
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 ;-)


Twxs

Avatar
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


Avatar
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

Avatar
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 Read_A( std::istream& );
void Read_B( std::istream& );
...
public:
void Read( 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_Mark
{
...
public:
virtual ~XML_Mark() {} // destructeur virtuel pour hierarchie polymorphe
virtual void print( std::ostream& ) = 0;
};

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

1 2