OVH Cloud OVH Cloud

XML en C++ : générer le xml et le parser

101 réponses
Avatar
noone
Bonjour,

je débute en C++ (j'ai fait un peu de C# avant)
L'avantage du C# était de pouvoir sérialiser facilement des objets c'est
à dire les stocker en XML.

Je ne sais pas trop comment m'y prendre en C++.

Quelle librairie utiliser (dans un projet utilisant déjà wxWidgets pour
l'interface graphique) ?

Pour les stocker je fais ceci :

// ===============================

#include <iostream> // pour cout
#include <fstream> // pour ofstream

using namespace std;

class Complexe {
public:
double x;
double y;

void Show()
{
cout << this->x << "+i*" << this->y << endl;
}
};

ostream & operator << (ostream & o,const Complexe & c)
{
return o
<< "<?xml version=\"1.0\"?>" << endl
<< "<Complexe" << " "
<< "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" << endl
<< "<Re>" << c.x << "</Re>" << endl
<< "<Im>" << c.y << "</Im>" << endl
<< "</Complexe>" << endl;
}


int main()
{
Complexe cplx;
cplx.x=1;
cplx.y=2;

cplx.Show();

ofstream ofs("cplx.xml");

ofs << cplx << endl;
cout << cplx << endl;
}

// ======================


C'est un peu lourd à gérer non ?

Donc en clair avez vous une technique pour générer du xml simplement (et
avec fiabilité) ?

Comment parser ensuite ce fichier XML ?

Merci d'avance de vos réponses.

10 réponses

7 8 9 10 11
Avatar
Olivier Azeau
Marc Boyer wrote:
drkm wrote:

Gabriel Dos Reis writes:

drkm writes:
| La question de la simplicité de la transformation est donc réglée.
^^^^^^^^^^^^^^^^^

voulais-tu dire « lisibilité » ?


Non. Ce n'était peut être pas clair. Je ne me souviens plus si
Olivier à expliqué ce qu'était XSLT en l'introduisant dans la
discussion.

Il s'agit d'un dialecte XML visant à représenter des règles de
transformation d'arbres XML. Lorsque l'on applique, au moyen d'un
processeur XSLT, un script XSLT constitué entre autre des deux modèles
qu'Olivier a donné, à un document comme :

<member name="m">
<complex real="0" imag="1"/>
</member>

on obtient la sortie :

m = #c(0 1)

En fait, avec ses modèles, on obtient plutôt (pas testé, plutôt un
peu au pif, mais ça devrait pas être loin) :



Ce qui m'ammènerait moi à dire qu'on à intéret à stocker ses
formats simples en ASCII, et le jour ou un besoin de transformation
d'arbre devient nécessaire, un petit coup de AWK nous fait
le XML, et puis on joue.



J'acquiesce.
Mais quand mes applis ne manipulent pas que des formats simples, je
stocke directement en XML.
Soit environ 100% des cas.



Avatar
Olivier Azeau
wrote:
drkm wrote:

writes:



Seulement, je ne connais pas de façon à gérer ces
identificateurs de façon générique.




Un genre de :



std::ostringstream oss ;
oss << ( void * ) & lObjet ;
oss.string() ;



ne convient pas, pour ce genre de cas ?



Et comment tu récupères l'information lors de la lecture ? Sur
une machine avec une autre architecture de pointeur, par
exemple ?

Il n'est pas donné que je puisse lire la sortie d'un void* sur
une autre machine. Et si je réussis à le lire, qu'est-ce que
j'en fait -- les objets sont prèsque certainement à d'autres
adresses.



Je les mets dans un tableau associatif ? Avec éventuellement une classe
pointeur qui gère ça de façon transparente ?
Si on n'a pas de contrainte de persistance des identifiants et pas trop
de problèmes de performance, ça peut passer, non ?



Avatar
drkm
Matthieu Moy writes:

La question n'est pas la manipulation de l'ASCII en général, mais la
manipulation d'un format particulier basé sur l'ASCII


Non. La question est « qu'est-ce qu'apporte XML par rapport à des
formats ASCII maisons ? » :

| > Dans la pratique, il y a encore peu de cas où XML se
| > justifie.


| Je ne suis pas tout à fait d'accord : XML (avec un DTD) permet
| d'échanger des données structurées complexes entre 2
| programmes quelconques, même s'ils sont écrits avec des
| langages très différents (C# d'un côté et Perl de l'autre par
| exemple).


et jusque là quelle la différence avec mes propes formats ASCII?


Une des différences avancées par Olivier dans ce contexte était
qu'il existe des langages où l'ASCII est difficilement manipulable, à
l'inverse de l'XML :

L'XML est facilement manipulable en d'autres langages que
C++, mais pas l'ASCII ?



C'est une façon de résumer la chose...


J'aimerais juste savoir de quels langages il parle.

--drkm


Avatar
Matthieu Moy
drkm writes:

Matthieu Moy writes:

La question n'est pas la manipulation de l'ASCII en général, mais la
manipulation d'un format particulier basé sur l'ASCII


Non. La question est « qu'est-ce qu'apporte XML par rapport à des
^^^

formats ASCII maisons ? » :
^^^^^^^^^^^^^^^^^^^^^


Tu ne parles donc pas d'ASCII en général, mais bien d'un format
maison. L'ASCII en soi n'est pas capable de representer des données
complexes (il est fait pour représenter des "char *", il le fait bien,
mais il ne fait que ça ...). Si tu veux sérialiser une classe dans un
format ASCII, tu vas avoir besoin de définir une grammaire ou quelque
chose du même genre pour dire comment tu represente tes données, ie
définir un niveau d'abstraction plus haut que le "char *". Selon la
grammaire que tu choisis, le format sera plus ou moins difficile a
exploiter depuis un autre language.

--
Matthieu


Avatar
drkm
Matthieu Moy writes:

drkm writes:

Matthieu Moy writes:

La question n'est pas la manipulation de l'ASCII en général, mais la
manipulation d'un format particulier basé sur l'ASCII


Non. La question est « qu'est-ce qu'apporte XML par rapport à des
^^^

formats ASCII maisons ? » :
^^^^^^^^^^^^^^^^^^^^^


Tu ne parles donc pas d'ASCII en général, mais bien d'un format
maison.


Bien sûr. Ce que je voulais dire ici, c'est que l'on parle des
différences entre un type de documents XML et un format plain text.
Et Olivier a introduit la notion de facilité de manipulation.

Il ne faut pas oublier qu'XML n'est pas un langage directement
exploitable, mais un méta-langage. Il sert de cadre à la définition
de langages (les applications XML, les types de documents XML). Une
fois que tu utilises ce cadre, il te faut encore analyser les éléments
du langage particulier.

Tout comme, pour un format plain text, tu utilises des caractères,
mais dois encore analyser les éléments du langage maison.

Et je trouves fallacieux de dire qu'il faut utiliser de l'XML plutôt
que du plain text parce que ce dernier sera difficilement manipulable
en dehors de C++ (ce qui ne serait pas le cas d'XML).

--drkm



Avatar
Gabriel Dos Reis
Matthieu Moy writes:

| drkm writes:
|
| > Matthieu Moy writes:
| >
| >> La question n'est pas la manipulation de l'ASCII en général, mais la
| >> manipulation d'un format particulier basé sur l'ASCII
| >
| > Non. La question est « qu'est-ce qu'apporte XML par rapport à des
| ^^^
| > formats ASCII maisons ? » :
| ^^^^^^^^^^^^^^^^^^^^^
|
| Tu ne parles donc pas d'ASCII en général, mais bien d'un format
| maison. L'ASCII en soi n'est pas capable de representer des données
| complexes (il est fait pour représenter des "char *", il le fait bien,
| mais il ne fait que ça ...). Si tu veux sérialiser une classe dans un
| format ASCII, tu vas avoir besoin de définir une grammaire ou quelque
| chose du même genre pour dire comment tu represente tes données, ie
| définir un niveau d'abstraction plus haut que le "char *".

Oui.

| Selon la
| grammaire que tu choisis, le format sera plus ou moins difficile a
| exploiter depuis un autre language.

Donc, on sait pas quoi.

-- Gaby
Avatar
Gabriel Dos Reis
drkm writes:

| Il ne faut pas oublier qu'XML n'est pas un langage directement
| exploitable, mais un méta-langage.

C'est, je crois, ce que nombre de gens oublient.

La méta-description peut être puissante, mais dans des applications
concretes elle n'est intéressante que quand elle est plus « simple » à
mettre en oeuvre que le langage objet.

-- Gaby
Avatar
Gabriel Dos Reis
Olivier Azeau writes:

[...]

| Tout ça pour dire que quand qqun a codé des classes C++ avec son Lex,
| son Yacc et ses opérations sémantiques, il n'a pas tellement envie de
| coder une exploitation des mêmes données avec un autre langage.

Tout est relatif.

| Si les mêmes choses ont été faites avec un max de technos autour du
| XML, la facture sera beaucoup moins douloureuse.

la facture en terme de quoi exactement ?

-- Gaby
Avatar
drkm
Olivier Azeau writes:

Reste le parser maison mais j'appelle ça une solution "difficile".


Justement, je n'aime pas cet a priori. Un format maison peut être
très simple, et n'exiger que des getline et une analyse fort simple de
chaîne. Ce qui peut être bien plus simple que de se lancer dans
l'utilisation d'un parseur XML. Mais cela dépend, évidemment.

[...]

Si les mêmes choses ont été faites avec un max de technos autour du XML,
la facture sera beaucoup moins douloureuse.


Mais utiliser un « max de technos autour du XML », ça a un coût.
Qui peut être bien plus élevé que l'utilisation d'un format maison,
bien pensé, documenté un minimum, et dont l'écriture d'un parseur peut
aller bien plus vite que l'utilisation d'un parseur XML pour un format
XML correspondant (sans parler de l'écriture des schémas, XSLT, etc.).
Qu'inclus-tu dans le calcul de ta facture ?

--drkm

Avatar
kanze
Olivier Azeau wrote:
wrote:
drkm wrote:

writes:

Seulement, je ne connais pas de façon à gérer ces
identificateurs de façon générique.


Un genre de :

std::ostringstream oss ;
oss << ( void * ) & lObjet ;
oss.string() ;

ne convient pas, pour ce genre de cas ?


Et comment tu récupères l'information lors de la lecture ?
Sur une machine avec une autre architecture de pointeur, par
exemple ?

Il n'est pas donné que je puisse lire la sortie d'un void*
sur une autre machine. Et si je réussis à le lire, qu'est-ce
que j'en fait -- les objets sont prèsque certainement à
d'autres adresses.


Je les mets dans un tableau associatif ? Avec éventuellement
une classe pointeur qui gère ça de façon transparente ? Si on
n'a pas de contrainte de persistance des identifiants et pas
trop de problèmes de performance, ça peut passer, non ?


Si le programme qui lit ne les traite que comme des chaînes de
caractères. Je suppose alors que c'est un générateur de chaîne
aléatoire comme un autre, avec l'avantage qu'il garantit que les
clés soient uniques automatiquement. Ceci dit, dans ce cas-là,
je n'en vois pas l'avantage sur ++nextId.

Note que dans le cas de l'utilisation de void*, tu n'es pas
garantie qu'un autre programme puisse les lire comme void*. Et
qu'il faut s'occuper des séparateurs. Dans le contexte de XML,
on ferait « dest << '"' << (void*)&obj << '"' », mais dans des
protocols plus simple, on ne veut pas forcément avoir à gérer
les chaînes arbitraires délimitées par des ". Or, si je sais que
++nextId ne génèrerait jamais que [1-9][0-9]*, c'est loin d'être
le cas avec (void*)&obj.

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




7 8 9 10 11