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

Avatar
Matthieu Moy
Laurent Deniau writes:

Et pourquoi veux-tu mettre toutes ces balises? Peut-etre que:

<Text>
Complex 1 2
</Text>


Tu peux aussi faire quelque chose comme

<format encoding="uuencode">
AUaueontsauOAUENUASNDEqauentONUNotauOAUNsoEANTUea
aUenaueOAUNEONATUSEanuetsAUENTaUENTaNUESDMKmeXIUN
</format>

si tu veux. Oui, on peut encapsuler n'importe quoi dans du XML, mais
l'intérêt du XML est un peu limité dans ce cas là ... (a part faire
plaisir au chef qui voulait du XML)

--
Matthieu

Avatar
Laurent Deniau
Jean-Marc Bourguet wrote:
Laurent Deniau writes:


Et pourquoi veux-tu mettre toutes ces balises?



Si je comprends bien, tu es en train de dire qu'il y a moyen de
detourner XML? Nous sommes d'accord, c'est une solution si XML est
impose par quelqu'un qui s'y connait vraiment pas.


Pas seulement, je dis aussi que l'on peut mettre le strict minimum pour
que la serialisation puisse reconstruire les objets tout en etant
compatible avec XML. A quoi ca sert que XML sache qu'un complexe a une
partie reelle et une partie imaginaire si tu ne veux pas ecrire faire de
calcul avec. Et meme a quoi ca sert que XML sache que l'objet serialise
entre les balises soit un complexe?

a+, ld.


Avatar
Laurent Deniau
Matthieu Moy wrote:
Laurent Deniau writes:


Et pourquoi veux-tu mettre toutes ces balises? Peut-etre que:

<Text>
Complex 1 2
</Text>



Tu peux aussi faire quelque chose comme

<format encoding="uuencode">
AUaueontsauOAUENUASNDEqauentONUNotauOAUNsoEANTUea
aUenaueOAUNEONATUSEanuetsAUENTaUENTaNUESDMKmeXIUN
</format>

si tu veux. Oui, on peut encapsuler n'importe quoi dans du XML, mais
l'intérêt du XML est un peu limité dans ce cas là ... (a part faire
plaisir au chef qui voulait du XML)


Qu'est que tu veux en faire de ton XML? On parle bien de serialisation
from/to C++ non? Si tu veux reutiliser les valeurs pour faire des
calculs via un calculateur ecrit en XML, alors d'accord des balises plus
precise sont necessaires, mais ce n'est plus de la serialisation pour du
C++.

a+, ld.


Avatar
Gabriel Dos Reis
Laurent Deniau writes:

[...]

| Chaque classe sait parser ses donnees via un Formater (deja discute de
| ca avec James il y a pas longtemps sur f.c.l.c ;-). La version est
| optionnelle. Par exemple un Array (tableau de pointeurs de type
| Object) de Double donnerait:
|
| Array 3
| Double 1.0
| Double 1.5
| Double 2.0
|
| Bref je ne me prends pas la tete avec XML...

Il me semble que nous avons des expériences similaires.

-- Gaby
Avatar
Nicolas Favre-Felix
Bonjour,
Pour rester dans le thread C++/XML mais en sortant de la sérialisation,
j'avais quelques questions sur des bibliothèques permettant de gérer du
XML, car celles citées plus haut traitent surtout de la serialisation.
J'ai essayé pas mal de libs permettant de gérer du XML, fait un petit
wrapper pour libXML, utilisé libxml++, expat, Xerces, Xalan, jeté un
petit coup d'oeil à la partie XML de Qt, mais rien de vraiment simple,
de vraiment pratique ne sort du lot. Soit les implémentations sont
tellement proches du DOM que c'est difficile à utiliser, soit le code
devient illisible avec des "xmlNewTextWriterFilename" de libXML. Il y a
une extension de PHP5, maintenant intégrée directement au langage, qui
s'appelle simpleXML et qui porte bien son nom.

Exemple tiré de http://www.php.net/simplexml :

$xml = simplexml_load_string($xmlstr);
/* For each <movie> node, we echo a separate <plot>. */
foreach ($xml->movie as $movie) {
echo $movie->plot, '<br />';
}
foreach ($xml->xpath('//character') as $character) {
echo $character->name, 'played by ', $character->actor, '<br />';
}
echo $xml->asXML();

C'est très simple, et exactement ce qu'il faut pour beaucoup de gens.
Malheureusement, il n'y a que des fonctions de "lecture", et aucune de
création de l'arbre.
J'avais donc commencé à faire quelque chose de similaire, avec Lex :

Node *n1 = new Node("abc");
Node *n2 = new Node("def");
n1->addText("Du texte");
n1->addChild(n2);
n1->addText("encore du texte");
n1->addChild("apres-def");
n2->addAttribute("attr1", "valeur1");
Node *dans_def = new Node("dans-def");
dans_def->addAttribute("id", "573");
n2->addChild(dans_def);

cout << n1->asXML() << "n";
qui sort ça : <abc>Du texte<def attr1="valeur1"><dans-def
id="573"/></def>encore du texte<apres-def/></abc>


Il y a aussi un static Node* Node::parseXML(std::string), qui fonctionne
sans vérification de conformité du XML. J'avais également commencé (un
tout petit peu) à recoder un XPath pour aller avec.
Je sais bien que ce n'est pas une bonne solution, et que bien qu'il y
ait pas mal de boulot dessus, il me manque beaucoup de choses. Je l'ai
simplement fait parce que je n'avais rien trouvé d'aussi simple.
Savez-vous si cela existe, en libre si possible ?

Merci.
Avatar
drkm
Laurent Deniau writes:

drkm wrote:

writes:

-- plus lisible par un être humain normalement constitué, et
-- plus simple à générer et surtout à parser (et donc, moins
consumateur du temps CPU).


Malheureusement, l'idée contraire est je pense fort répandue (XML,
compromis lisible par les humains et les machines).


question de point de vue:

<MyFormat>
Complex 1 2
</MyFormat>

Pas lisible? Complique?


Ce n'est pas exactement la question. Je trouve « (1;2) » *plus*
lisible, et par un humain, et par une machine.

XML a ses applications, mais je ne suis pas d'accord avec l'argument
de vente comme quoi c'est *le* compromis sur la lisibilité humaine et
machine.

--drkm



Avatar
drkm
Nicolas Favre-Felix writes:

Tout d'abord, cette discussion est plus adaptée sur f.c.t.xml, je
pense. X-Post et Fu2 (histoire d'alimenter un peu fctx ;-p).

Savez-vous si cela existe, en libre si possible ?


Je n'ai pas vraiment compris ce que tu cherches. Mais il me semble
(ça fait un moment que je n'y ai plus regardé) que la libxml du projet
Gnome et Xerces du projet Apache ont l'air plutôt riches en
fonctionalités.

Il me semble qu'il y a moyen d'écrire du code très clair par exemple
en se servant de l'implémentation SAX de la libxml. Tes handlers
créent les objets dont tu as besoin, à la lecture. À l'écriture, une
hiérarchie parallèle crée les différents noeuds correspondant aux
objets à sauver.

Si la conception de tes hiérarchies de lecteurs et d'écrivains est
bien pensée, il devrait même y avoir moyen de changer d'implémentation
SAX assez facilement.

Que cherches-tu, plus précisément ?

--drkm

Avatar
Loïc Joly
wrote:

| L'existence d'un mécanisme de validation via une DTD pour le


contrôle

| des erreurs ?

Mais cela dépend de mon propre format ASCII : est-il plus simple
d'utiliser ton validateur DTD que mon propre vérificateur de format
qui eput Être de loin plus simple selon mon propre format ASCII ?
Mon propre vérificateur peut être aussi auto-correcteur ou non
redondant.


Oui, yapluka l'écrire, et probablement le refaire (ou le modifier)
pour chaque nouveau projet, si les contraintes sont différentes...


C'est là dessus le mauvais point d'XML dans mon expérience. Un parseur
classique, en cas de modification des classes, demande à modifier :
- La classe
- Les fichiers de données
- Le code qui parse
Ce qui en exploitation se traduit par un programme et un fichier.


Un parseur XML demande lui de modifier :
- La classe
- Les fichiers de données
- Le code qui parse
- Les schéma
Ce qui en exploitation se traduit par un programme et deux fichiers.

Donc, pour le développeur ou la personne qui déploie, il est moins
facile à modifier. On l'a clairement expérimenté au boulot. Si on devait
reprende ce programme, le remplacement de ce format de fichier par un
truc issu de boost::serialisation serait certainement l'une des
premières étapes. En terme de pocker, XML, on a payé pour voir, c'était
du bluff.


| L'existence de langages adaptés pour traiter ces informations lors


de

| l'échange ? (XSLT)



Ca peut être je pense un avantage d'XML, surtout qu'on peut imaginer des
outils faisant ce genre de boulot sans programmation.


Mais, cela peut être aussi le cas de mon propre format ASCII (AWK,
Perl, ...).


On parle de C++, non ?


| L'idiome qui va permettre à un autre développeur de comprendre
| immédiatement ce qui a été fait ?

Mais cela peut être aussi le cas de mon propre format ASCII.



Entre ton format ASCII maison (aussi bien conçu soit-il), et un
standard du W3C, il n'y a pas photo pour ce qui est de la facilité de
trouver un développeur compétent et capable de réutiliser facilement
le format...


Oui, je pense que le format maison est largement gagnant. Surtout si les
données sont un minimum complexes (il n'y a pas de notion de référence
en XML, la validation que peuvent faire les schémas est assez limitée et
locale et demande une phase ultérieure, parser une formule mathématique
en XML, je rigole...)

Bref.


Ta réaction me fait un peu penser aux gens qui disent "à quoi ca sert
std::vector, je peux très bien faire mes tableaux à la main". Certes
on peut tout faire à la main, maintenant quand est-ce que c'est
rentable/intéressant, et quand est-ce qu'on a intérêt a choisir une
solution "standard", éprouvée et déjà faite...


Lex et Yacc sont plus éprouvé qu'XML.

Je peux voir deux avantages supplémentaires à XML :
- Il existe des outils génériques (genre XML Spy) permettant d'afficher
un document XML en mode texte mis en page. Dans ce cas (et dans ce cas
seulement), et si le contenu est plutôt long mais simple, il est
possible que ce format soit plus lisible par un être humain qu'un format
propriétaire.
- Je pense qu'un développeur mauvais mais besogneux et bourin arrivera à
tirer un meilleur résultat d'XML que d'un parseur ad hoc.

--
Loïc


Avatar
Olivier Azeau
Gabriel Dos Reis wrote:
writes:
[snip]


| on peut tout faire à la main, maintenant quand est-ce que c'est
| rentable/intéressant, et quand est-ce qu'on a intérêt a choisir une
| solution "standard", éprouvée et déjà faite...

Mais c'est quoi la solution standard ici ?


Une solution où les analyses lexicales et syntaxiques de l'échange de
données ne coutent rien à écrire et où l'on va donc pouvoir se
concentrer sur la sémantique.
Le traitement sémantique est d'ailleurs relativement aisé si on prend la
peine de faire un peu de XPath.

Une solution où même si la lisibilité des données par un humain n'est
pas immédiate (lire du XML, même bien formatté, avec un editeur de texte
de base c'est n'importe quoi), elle ne coute pas bien cher avec un peu
d'XSLT.

Une solution qui, quoi que l'on en dise, n'est pas plus chère en CPU que
n'importe quelle autre en termes de parsing.
Quiconque fait un peu de profiling sur du parsing XML en C++ se rend
compte que l'essentiel du temps est passé à allouer les objets qui vont
réceptionner la donnée et à copier la donnée elle-même, c'est à dire des
choses qu'il faut faire quel que soit le formalisme d'échange utilisé.

...


Analogie pour analogie, c'est comme si tu me disais que je dois
systématiquement choisir d'écrire mes programmes en C++, en place et
lieu de Python ou Perl parce que C++ a un standard ISO.



L'analogie serait plutôt de dire que, quand on fait du C++ il faut
utiliser la STL en lieu et place de classes faites maison pour gérer des
listes ou des chaînes de caractère.
On ne va pas utiliser la STL parce qu'un groupe de personnes l'a
"standardisé" mais parce que l'on va y trouver toute une panoplie de
services que l'on aurait bien du mal à réécrire soi même. Et peut être
aussi un peu parce qu'un développeur pris au hasard aura bien plus de
chances de comprendre un code C++ qu'il ne connait pas si celui-ci
utilise la STL.

Avatar
Olivier Azeau
Loïc Joly wrote:
wrote:

| L'existence d'un mécanisme de validation via une DTD pour le



contrôle

| des erreurs ?

Mais cela dépend de mon propre format ASCII : est-il plus simple
d'utiliser ton validateur DTD que mon propre vérificateur de format
qui eput Être de loin plus simple selon mon propre format ASCII ?
Mon propre vérificateur peut être aussi auto-correcteur ou non
redondant.



Oui, yapluka l'écrire, et probablement le refaire (ou le modifier)
pour chaque nouveau projet, si les contraintes sont différentes...



C'est là dessus le mauvais point d'XML dans mon expérience. Un parseur
classique, en cas de modification des classes, demande à modifier :
- La classe
- Les fichiers de données
- Le code qui parse
Ce qui en exploitation se traduit par un programme et un fichier.


Un parseur XML demande lui de modifier :
- La classe
- Les fichiers de données
- Le code qui parse
- Les schéma
Ce qui en exploitation se traduit par un programme et deux fichiers.

Donc, pour le développeur ou la personne qui déploie, il est moins
facile à modifier. On l'a clairement expérimenté au boulot. Si on devait
reprende ce programme, le remplacement de ce format de fichier par un
truc issu de boost::serialisation serait certainement l'une des
premières étapes. En terme de pocker, XML, on a payé pour voir, c'était
du bluff.



J'amène pour ma part une expérience complètement opposée.
Je me souviens avoir vécu un petit enfer avec la sérialisation MFC
(CArchive & co), tout particulièrement en ce qui concerne la
modification des fichiers de données lors des modifications de classe :
pas d'autre solution que de disposer d'un code des classes sachant
désérialiser l'ancien format et sérialiser le nouveau.
Alors que si on avait eu dans ce cas là un stockage XML, on aurait fait
ça en un rien de temps avec une pincée de XSLT.

Compter le nombre de programmes et de fichiers à modifier, cela ne veut
rien dire si modifier les fichiers prend 10 fois plus de temps dans un
cas que dans l'autre.