Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

MINXL (MINIMALIST XML LIBRARY) : GÉNÉRATEUR/ANALYSEUR/TRAITEMENT DE FLUX/FICHIERS XML EN C++


Information sur la source

Catégorie :Système Classé sous : xml, parseur, parser, manipulation, arbre Niveau : Initié Date de création : 18/05/2005 Date de mise à jour : 16/03/2008 09:15:48 Vu / téléchargé: 10 117 / 815

Note :
9,13 / 10 - par 8 personnes
9,13 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (74)
Ajouter un commentaire et/ou une note

Description

* Libraitrie MinXL : Minimalist XML *

Il s'agit d'une librairie codée en C++ et basée sur la STL uniquement. Le code est donc portable. Il a été compilé sous Windows2000/MinGW/DevCpp, GNU/linux/Eclipse/CDT et sous WindowsXP/Cygwin/Eclipse/CDT avec succès.

Le source de cette librairie se compose de deux fichiers autonomes : xml.hpp (en-tête C++) et xml.cpp (source C++). Un fichier supplémentaire "xml_test.cpp" est un programme principale de test (25 tests successifs + 2 exemples commentés). Ce dernier donne différents cas d'utilisation de la librairie MinXL, en plus de vérifier son bon fonctionnement point par point. Les sources sont documentés en anglais (pauvre mais je l'espère lisible par tous).

---

Cette librairie contient deux classes regroupées au sein du namespace MinXL :
- t_xml_node : classe élémentaire offrant une abstraction d'un noeud/arbre XML (formé d'une chaine 'clé', de chaines 'attributs' et d'une chaine 'valeur'),
- t_xml_manip : classe facilitant le traitement d'un arbre XML complexe offrant une interface proche d'une invite de commande DOS/Linux (on parcours l'arbre XML comme un système de fichiers par des commandes/méthodes du genre 'list', 'make', 'remove', 'copy', 'move', 'read', 'write', etc...).

---

Limitation : le 'parser' ignore seulement le prologue (ex.: <?xxxx?>) et les commentaires (ex.: <!-- xxx -->), sans les décoder. Les performances du 'parser' sont également tres pauvres (constaté par yAAm). Une optimisation du code est en cours sans nuire à sa lisibilité (gain de rapidité de l'ordre de 500% actuellement, par rapport à la première release).

---

Toutes remarques sont les bienvenues. Je suis prêt à modifier le code source pour prendre en charge de nouvelles fonctionnalités suggérées par un éventuel utilisateur intéressé. Merci.

---

Ce projet est disponible sur SourceForge.Net : Unix Name= "minxl". CVS à jour.

---

Cordialement,
Xterm-in-Hate.
 

Source

  • /////////////////////////////////////////////////////////////////////////////
  • // CECI EST UN APPERCU DU CODE ZIPPE....
  • /////////////////////////////////////////////////////////////////////////////
  • struct t_xml_node
  • {
  • // constructor
  • t_xml_node( std::string const & key = "_EMPTY_", std::string const & value = "" );
  • // destructor
  • virtual ~t_xml_node();
  • // copy constructor
  • t_xml_node( t_xml_node const & node );
  • // assignment
  • t_xml_node & operator=( t_xml_node const & node );
  • // key accessers
  • std::string const & key() const;
  • std::string & key();
  • // value accessers
  • std::string const & value() const;
  • std::string & value();
  • // number of attributes
  • std::size_t nb_attributes() const;
  • // add an attributes
  • void insert_attribute( std::string const & attribute, std::string const & value );
  • // remove an attributes
  • void remove_attribute( std::size_t const & index );
  • // remove an attribute through string indexer
  • void remove_attribute( std::string const & attribute );
  • // get an attribute
  • std::string const & attribute_at( std::size_t const & index ) const;
  • std::string & attribute_at( std::size_t const & index );
  • // get an attribute associated value
  • std::string const & attribute_value_at( std::size_t const & index ) const;
  • std::string & attribute_value_at( std::size_t const & index );
  • // get an attribute associated through string indexer (key_suffix = "aaaa:n", "aaaa"+":0" by default suffix)
  • std::string const & attribute_value_at( std::string const & attribute ) const;
  • std::string & attribute_value_at( std::string const & attribute );
  • // number of children
  • std::size_t nb_children() const;
  • // add a child
  • void insert_child( t_xml_node const & child );
  • // remove a child
  • void remove_child( std::size_t const & index );
  • // remove a child through string indexer (key_suffix = "aaaa:n", "aaaa"+":0" by default suffix)
  • void remove_child( std::string const & key_suffix );
  • // get a child
  • t_xml_node const & child_at( std::size_t const & index ) const;
  • t_xml_node & child_at( std::size_t const & index );
  • // get a child through indexer (key_suffix = "aaaa:n", "aaaa"+":0" by default suffix)
  • t_xml_node const & child_at( std::string const & key_suffix ) const;
  • t_xml_node & child_at( std::string const & key_suffix );
  • // build : transform a tree/node into a XML stream/file
  • void build_to_file( std::string const & path_filename ) const;
  • std::string build_to_str() const;
  • // parse : transform a XML stream/file into a tree/node
  • void parse_from_file( std::string const & path_filename );
  • void parse_from_str( std::string const & str );
  • };
  • /////////////////////////////////////////////////////////////////////////////
  • // CECI EST UN APPERCU DU CODE ZIPPE....
  • /////////////////////////////////////////////////////////////////////////////
  • struct t_xml_manip
  • {
  • // constructor
  • t_xml_manip( t_xml_node & root );
  • // key management
  • std::vector< std::string > ls( std::string const & path ) const; // list keys
  • void mk( std::string const & path ) const; // make new key or new attribute
  • void rm( std::string const & path ) const; // remove key or attribute
  • void mv( std::string const & src_path, std::string const & dst_path ) const; // move key
  • void cp( std::string const & src_path, std::string const & dst_path ) const; // copy key
  • // key-value and attribute-value read/write
  • std::string const & operator()( std::string const & path ) const; // read key-value or attribute-value
  • std::string & operator()( std::string const & path ); // read/write key-value or attribute-value
  • std::string const & read( std::string const & path ) const; // read key-value or attribute-value
  • void write( std::string const & value, std::string const & path ) const; // write key-value or attribute-value
  • }
  • /////////////////////////////////////////////////////////////////////////////
  • // CECI EST UN APPERCU DU CODE ZIPPE....
  • /////////////////////////////////////////////////////////////////////////////
  • {
  • // example 1.1.1 :
  • //
  • // player_list (number_of_players : 2)
  • // +---> player (id : 0001)
  • // | +---> name : xterm-in-hate
  • // | +---> level : 39
  • // | +---> class : berseker
  • // | +---> experience : 8012
  • // | +---> position
  • // | | +---> world : earth
  • // | | +---> xcord : 111
  • // | | +---> ycord : 452
  • // | | +---> zcord : 37
  • // | | +---> xyangle : 162
  • // | | +---> xzangle : -9
  • // | +---> health : 120
  • // | +---> mana : 270
  • // +---> player (id : 0002)
  • // . +---> name : guest
  • // . +---> level : 1
  • // . +---> class : paladin
  • // . +---> experience : 0
  • // . +---> position
  • // . | +---> world : earth
  • // . | +---> xcord : 118
  • // . | +---> ycord : 493
  • // . | +---> zcord : 38
  • // . | +---> xyangle : 25
  • // . | +---> xzangle : 0
  • // . +---> health : 50
  • // . +---> mana : 22
  • cout << "EXAMPLE#1.1.1" << endl;
  • // root node : player list
  • t_xml_node root( "player_list", "" );
  • root.insert_attribute("number_of_players","2");
  • // child 1 node : player
  • t_xml_node c1( "player", "" );
  • c1.insert_attribute( "id", "0001" );
  • // child 1-1 node : name
  • t_xml_node c11( "name", "xterm-in-hate" );
  • c1.insert_child(c11);
  • // child 1-2 node : level
  • t_xml_node c12( "level", "39" );
  • c1.insert_child(c12);
  • // child 1-3 node : class
  • t_xml_node c13( "class", "berseker" );
  • c1.insert_child(c13);
  • // child 1-4 node : experience
  • t_xml_node c14( "experience", "8012" );
  • c1.insert_child(c14);
  • // child 1-5 node : position
  • t_xml_node c15( "position", "" );
  • // child 1-5-1 node : world
  • t_xml_node c151( "world", "earth" );
  • c15.insert_child(c151);
  • // child 1-5-2 node : xcord
  • t_xml_node c152( "xcord", "111" );
  • c15.insert_child(c152);
  • // child 1-5-3 node : ycord
  • t_xml_node c153( "ycord", "452" );
  • c15.insert_child(c153);
  • // child 1-5-4 node : zcord
  • t_xml_node c154( "zcord", "37" );
  • c15.insert_child(c154);
  • // child 1-5-5 node : xyangle
  • t_xml_node c155( "xyangle", "162" );
  • c15.insert_child(c155);
  • // child 1-5-6 node : xzangle
  • t_xml_node c156( "xzangle", "-9" );
  • c15.insert_child(c156);
  • // child 1-5 node : position (end)
  • c1.insert_child(c15);
  • // child 1-6 node : health
  • t_xml_node c16( "health", "120" );
  • c1.insert_child(c16);
  • // child 1-7 node : mana
  • t_xml_node c17( "mana", "270" );
  • c1.insert_child(c17);
  • // child 1 node : player (end)
  • root.insert_child(c1);
  • // child 2 node : player
  • t_xml_node c2( "player", "" );
  • c2.insert_attribute( "id", "0002" );
  • // child 2-1 node : name
  • t_xml_node c21( "name", "guest" );
  • c2.insert_child(c21);
  • // child 2-2 node : level
  • t_xml_node c22( "level", "1" );
  • c2.insert_child(c22);
  • // child 2-3 node : class
  • t_xml_node c23( "class", "paladin" );
  • c2.insert_child(c23);
  • // child 2-4 node : experience
  • t_xml_node c24( "experience", "0" );
  • c2.insert_child(c24);
  • // child 2-5 node : position
  • t_xml_node c25( "position", "" );
  • // child 2-5-1 node : world
  • t_xml_node c251( "world", "earth" );
  • c25.insert_child(c251);
  • // child 2-5-2 node : xcord
  • t_xml_node c252( "xcord", "118" );
  • c25.insert_child(c252);
  • // child 2-5-3 node : ycord
  • t_xml_node c253( "ycord", "493" );
  • c25.insert_child(c253);
  • // child 2-5-4 node : zcord
  • t_xml_node c254( "zcord", "38" );
  • c25.insert_child(c254);
  • // child 2-5-5 node : xyangle
  • t_xml_node c255( "xyangle", "25" );
  • c25.insert_child(c255);
  • // child 2-5-6 node : xzangle
  • t_xml_node c256( "xzangle", "0" );
  • c25.insert_child(c256);
  • // child 2-5 node : position (end)
  • c2.insert_child(c25);
  • // child 2-6 node : health
  • t_xml_node c26( "health", "50" );
  • c2.insert_child(c26);
  • // child 2-7 node : mana
  • t_xml_node c27( "mana", "22" );
  • c2.insert_child(c27);
  • // child 2 node : player (end)
  • root.insert_child(c2);
  • // build XML file/stream
  • cout << root.build() << endl;
  • }
  • {
  • // example 2.1.1 :
  • //
  • // player_list (number_of_players : 2)
  • // +---> player (id : 0001)
  • // | +---> name : xterm-in-hate
  • // | +---> level : 39
  • // | +---> class : berseker
  • // | +---> experience : 8012
  • // | +---> position
  • // | | +---> world : earth
  • // | | +---> xcord : 111
  • // | | +---> ycord : 452
  • // | | +---> zcord : 37
  • // | | +---> xyangle : 162
  • // | | +---> xzangle : -9
  • // | +---> health : 120
  • // | +---> mana : 270
  • // +---> player (id : 0002)
  • // . +---> name : guest
  • // . +---> level : 1
  • // . +---> class : paladin
  • // . +---> experience : 0
  • // . +---> position
  • // . | +---> world : earth
  • // . | +---> xcord : 118
  • // . | +---> ycord : 493
  • // . | +---> zcord : 38
  • // . | +---> xyangle : 25
  • // . | +---> xzangle : 0
  • // . +---> health : 50
  • // . +---> mana : 22
  • cout << "EXAMPLE#2.1.1" << endl;
  • // root node : player list
  • t_xml_node root( "player_list", "" );
  • t_xml_manip m( root );
  • // root node : player list
  • m.mk("/player_list/.number_of_players");
  • m("/player_list/.number_of_players") = "2";
  • // player 1
  • m.mk("/player_list/player");
  • m.mk("/player_list/player:0/.id");
  • m("/player_list/player:0/.id") = "0001";
  • // player 1 name
  • m.mk("/player_list/player:0/name");
  • m("/player_list/player:0/name") = "xterm-in-hate";
  • // player 1 level
  • m.mk("/player_list/player:0/level");
  • m("/player_list/player:0/level") = "39";
  • // player 1 class
  • m.mk("/player_list/player:0/class");
  • m("/player_list/player:0/class") = "berseker";
  • // player 1 experience
  • m.mk("/player_list/player:0/experience");
  • m("/player_list/player:0/experience") = "8012";
  • // player 1 position
  • m.mk("/player_list/player:0/position");
  • m.mk("/player_list/player:0/position/world");
  • m("/player_list/player:0/position/world") = "earth";
  • m.mk("/player_list/player:0/position/xcord");
  • m("/player_list/player:0/position/xcord") = "111";
  • m.mk("/player_list/player:0/position/ycord");
  • m("/player_list/player:0/position/ycord") = "452";
  • m.mk("/player_list/player:0/position/zcord");
  • m("/player_list/player:0/position/zcord") = "37";
  • m.mk("/player_list/player:0/position/xyangle");
  • m("/player_list/player:0/position/xyangle") = "162";
  • m.mk("/player_list/player:0/position/xzangle");
  • m("/player_list/player:0/position/xzangle") = "-9";
  • // player 1 health
  • m.mk("/player_list/player:0/health");
  • m("/player_list/player:0/health") = "120";
  • // player 1 mana
  • m.mk("/player_list/player:0/mana");
  • m("/player_list/player:0/mana") = "270";
  • // player 2
  • m.mk("/player_list/player");
  • m.mk("/player_list/player:1/.id");
  • m("/player_list/player:1/.id") = "0002";
  • // player 2 name
  • m.mk("/player_list/player:1/name");
  • m("/player_list/player:1/name") = "guest";
  • // player 2 level
  • m.mk("/player_list/player:1/level");
  • m("/player_list/player:1/level") = "1";
  • // player 2 class
  • m.mk("/player_list/player:1/class");
  • m("/player_list/player:1/class") = "paladin";
  • // player 2 experience
  • m.mk("/player_list/player:1/experience");
  • m("/player_list/player:1/experience") = "0";
  • // player 2 position
  • m.mk("/player_list/player:1/position");
  • m.mk("/player_list/player:1/position/world");
  • m("/player_list/player:1/position/world") = "earth";
  • m.mk("/player_list/player:1/position/xcord");
  • m("/player_list/player:1/position/xcord") = "118";
  • m.mk("/player_list/player:1/position/ycord");
  • m("/player_list/player:1/position/ycord") = "493";
  • m.mk("/player_list/player:1/position/zcord");
  • m("/player_list/player:1/position/zcord") = "38";
  • m.mk("/player_list/player:1/position/xyangle");
  • m("/player_list/player:1/position/xyangle") = "25";
  • m.mk("/player_list/player:1/position/xzangle");
  • m("/player_list/player:1/position/xzangle") = "0";
  • // player 2 health
  • m.mk("/player_list/player:1/health");
  • m("/player_list/player:1/health") = "50";
  • // player 2 mana
  • m.mk("/player_list/player:1/mana");
  • m("/player_list/player:1/mana") = "22";
  • // build XML file/stream
  • cout << root.build() << endl;
  • }
  • /////////////////////////////////////////////////////////////////////////////
  • // CECI EST UN APPERCU DU CODE ZIPPE....
  • /////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CECI EST UN APPERCU DU CODE ZIPPE....
/////////////////////////////////////////////////////////////////////////////

	struct t_xml_node
	{
		// constructor
		t_xml_node( std::string const & key = "_EMPTY_", std::string const & value = "" );
		
		// destructor
		virtual ~t_xml_node();
		
		// copy constructor
		t_xml_node( t_xml_node const & node );
		
		// assignment
		t_xml_node & operator=( t_xml_node const & node );
		
		// key accessers
		std::string const & key() const;
		std::string & key();
		
		// value accessers
		std::string const & value() const;
		std::string & value();	
		
		// number of attributes
		std::size_t nb_attributes() const;

		// add an attributes
		void insert_attribute( std::string const & attribute, std::string const & value );

		// remove an attributes
		void remove_attribute( std::size_t const & index );
		// remove an attribute through string indexer
		void remove_attribute( std::string const & attribute );

		// get an attribute
		std::string const & attribute_at( std::size_t const & index ) const;
		std::string & attribute_at( std::size_t const & index );
		// get an attribute associated value
		std::string const & attribute_value_at( std::size_t const & index ) const;
		std::string & attribute_value_at( std::size_t const & index );
		// get an attribute associated through string indexer (key_suffix = "aaaa:n", "aaaa"+":0" by default suffix)
		std::string const & attribute_value_at( std::string const & attribute ) const;
		std::string & attribute_value_at( std::string const & attribute );

		// number of children
		std::size_t nb_children() const;

		// add a child	
		void insert_child( t_xml_node const & child );

		// remove a child
		void remove_child( std::size_t const & index );
		// remove a child through string indexer (key_suffix = "aaaa:n", "aaaa"+":0" by default suffix)
		void remove_child( std::string const & key_suffix );

		// get a child
		t_xml_node const & child_at( std::size_t const & index ) const;
		t_xml_node & child_at( std::size_t const & index );
		// get a child through indexer (key_suffix = "aaaa:n", "aaaa"+":0" by default suffix)
		t_xml_node const & child_at( std::string const & key_suffix ) const;
		t_xml_node & child_at( std::string const & key_suffix );

		// build : transform a tree/node into a XML stream/file
		void build_to_file( std::string const & path_filename ) const;
		std::string build_to_str() const;
		
		// parse : transform a XML stream/file into a tree/node
		void parse_from_file( std::string const & path_filename );
		void parse_from_str( std::string const & str );
	};

/////////////////////////////////////////////////////////////////////////////
// CECI EST UN APPERCU DU CODE ZIPPE....
/////////////////////////////////////////////////////////////////////////////

	struct t_xml_manip
	{
		// constructor
		t_xml_manip( t_xml_node & root );
		
		// key management
		std::vector< std::string > ls( std::string const & path ) const; // list keys
		void mk( std::string const & path ) const; // make new key or new attribute
		void rm( std::string const & path ) const; // remove key or attribute
		void mv( std::string const & src_path, std::string const & dst_path ) const; // move key
		void cp( std::string const & src_path, std::string const & dst_path ) const; // copy key
				
		// key-value and attribute-value read/write
		std::string const & operator()( std::string const & path ) const; // read key-value or attribute-value
		std::string & operator()( std::string const & path ); // read/write key-value or attribute-value
		std::string const & read( std::string const & path ) const; // read key-value or attribute-value
		void write( std::string const & value, std::string const & path ) const; // write key-value or attribute-value
}

/////////////////////////////////////////////////////////////////////////////
// CECI EST UN APPERCU DU CODE ZIPPE....
/////////////////////////////////////////////////////////////////////////////

{
	 // example 1.1.1 :
	 // 	           
	 // player_list (number_of_players : 2)
	 // +---> player (id : 0001) 	       
	 // |     +---> name : xterm-in-hate 	
	 // |     +---> level : 39 	            
	 // |     +---> class : berseker 	    
	 // |     +---> experience : 8012 	    
	 // |     +---> position 	            
	 // |     |     +---> world : earth 	
	 // |     |     +---> xcord : 111 	   
	 // |     |     +---> ycord : 452 	 
	 // |     |     +---> zcord : 37 	 
	 // |     |     +---> xyangle : 162 	 
	 // |     |     +---> xzangle : -9 	 
	 // |     +---> health : 120 	 
	 // |     +---> mana : 270 	 
	 // +---> player (id : 0002) 	 
	 // .     +---> name : guest 	 
	 // .     +---> level : 1 	 
	 // .     +---> class : paladin 	 
	 // .     +---> experience : 0 	 
	 // .     +---> position 	 
	 // .     |     +---> world : earth 	 
	 // .     |     +---> xcord : 118 	 
	 // .     |     +---> ycord : 493 	 
	 // .     |     +---> zcord : 38 	 
	 // .     |     +---> xyangle : 25 	 
	 // .     |     +---> xzangle : 0 	 
	 // .     +---> health : 50 	 
	 // .     +---> mana : 22 	 
     cout << "EXAMPLE#1.1.1" << endl; 	 
     // root node : player list 	 
     t_xml_node root( "player_list", "" ); 	 
     root.insert_attribute("number_of_players","2"); 	 
     // child 1 node : player 	 
     t_xml_node c1( "player", "" ); 	 
     c1.insert_attribute( "id", "0001" ); 	 
     // child 1-1 node : name 	 
     t_xml_node c11( "name", "xterm-in-hate" ); 	 
     c1.insert_child(c11); 	 
     // child 1-2 node : level 	 
     t_xml_node c12( "level", "39" ); 	 
     c1.insert_child(c12); 	 
     // child 1-3 node : class 	 
     t_xml_node c13( "class", "berseker" ); 	 
     c1.insert_child(c13); 	 
     // child 1-4 node : experience 	 
     t_xml_node c14( "experience", "8012" ); 	 
     c1.insert_child(c14); 	 
     // child 1-5 node : position 	 
     t_xml_node c15( "position", "" ); 	 
     // child 1-5-1 node : world 	 
     t_xml_node c151( "world", "earth" ); 	 
     c15.insert_child(c151); 	 
     // child 1-5-2 node : xcord 	 
     t_xml_node c152( "xcord", "111" ); 	 
     c15.insert_child(c152); 	 
     // child 1-5-3 node : ycord 	 
     t_xml_node c153( "ycord", "452" ); 	 
     c15.insert_child(c153); 	 
     // child 1-5-4 node : zcord 	 
     t_xml_node c154( "zcord", "37" ); 	 
     c15.insert_child(c154); 	 
     // child 1-5-5 node : xyangle 	 
     t_xml_node c155( "xyangle", "162" ); 	 
     c15.insert_child(c155); 	 
     // child 1-5-6 node : xzangle 	 
     t_xml_node c156( "xzangle", "-9" ); 	 
     c15.insert_child(c156); 	 
     // child 1-5 node : position (end) 	 
     c1.insert_child(c15); 	 
     // child 1-6 node : health 	 
     t_xml_node c16( "health", "120" ); 	 
     c1.insert_child(c16); 	 
     // child 1-7 node : mana 	 
     t_xml_node c17( "mana", "270" ); 	 
     c1.insert_child(c17); 	 
     // child 1 node : player (end) 	 
     root.insert_child(c1); 	 
     // child 2 node : player 	 
     t_xml_node c2( "player", "" ); 	 
     c2.insert_attribute( "id", "0002" ); 	 
     // child 2-1 node : name 	 
     t_xml_node c21( "name", "guest" ); 	 
     c2.insert_child(c21); 	  
     // child 2-2 node : level 	 
     t_xml_node c22( "level", "1" ); 	 
     c2.insert_child(c22); 	 
     // child 2-3 node : class 	 
     t_xml_node c23( "class", "paladin" ); 	 
     c2.insert_child(c23); 	 
     // child 2-4 node : experience 	 
     t_xml_node c24( "experience", "0" ); 	 
     c2.insert_child(c24); 	 
     // child 2-5 node : position 	 
     t_xml_node c25( "position", "" ); 	 
     // child 2-5-1 node : world 	 
     t_xml_node c251( "world", "earth" ); 	 
     c25.insert_child(c251); 	 
     // child 2-5-2 node : xcord 	 
     t_xml_node c252( "xcord", "118" ); 	 
     c25.insert_child(c252); 	 
     // child 2-5-3 node : ycord 	 
     t_xml_node c253( "ycord", "493" ); 	 
     c25.insert_child(c253); 	 
     // child 2-5-4 node : zcord 	 
     t_xml_node c254( "zcord", "38" ); 	 
     c25.insert_child(c254); 	 
     // child 2-5-5 node : xyangle 	 
     t_xml_node c255( "xyangle", "25" ); 	 
     c25.insert_child(c255); 	 
     // child 2-5-6 node : xzangle 	 
     t_xml_node c256( "xzangle", "0" ); 	 
     c25.insert_child(c256); 	 
     // child 2-5 node : position (end) 	 
     c2.insert_child(c25); 	 
     // child 2-6 node : health 	 
     t_xml_node c26( "health", "50" ); 	 
     c2.insert_child(c26); 	 
     // child 2-7 node : mana 	 
     t_xml_node c27( "mana", "22" ); 	 
     c2.insert_child(c27); 	 
     // child 2 node : player (end) 	 
     root.insert_child(c2); 	 
     // build XML file/stream 	 
     cout << root.build() << endl;
}
{
	 // example 2.1.1 :
	 // 	           
	 // player_list (number_of_players : 2)
	 // +---> player (id : 0001) 	       
	 // |     +---> name : xterm-in-hate 	
	 // |     +---> level : 39 	            
	 // |     +---> class : berseker 	    
	 // |     +---> experience : 8012 	    
	 // |     +---> position 	            
	 // |     |     +---> world : earth 	
	 // |     |     +---> xcord : 111 	   
	 // |     |     +---> ycord : 452 	 
	 // |     |     +---> zcord : 37 	 
	 // |     |     +---> xyangle : 162 	 
	 // |     |     +---> xzangle : -9 	 
	 // |     +---> health : 120 	 
	 // |     +---> mana : 270 	 
	 // +---> player (id : 0002) 	 
	 // .     +---> name : guest 	 
	 // .     +---> level : 1 	 
	 // .     +---> class : paladin 	 
	 // .     +---> experience : 0 	 
	 // .     +---> position 	 
	 // .     |     +---> world : earth 	 
	 // .     |     +---> xcord : 118 	 
	 // .     |     +---> ycord : 493 	 
	 // .     |     +---> zcord : 38 	 
	 // .     |     +---> xyangle : 25 	 
	 // .     |     +---> xzangle : 0 	 
	 // .     +---> health : 50 	 
	 // .     +---> mana : 22 	 
     cout << "EXAMPLE#2.1.1" << endl; 	 
     // root node : player list 	 
     t_xml_node root( "player_list", "" ); 	 
     t_xml_manip m( root );
     // root node : player list 	 
     m.mk("/player_list/.number_of_players");
     m("/player_list/.number_of_players") = "2";
     // player 1
     m.mk("/player_list/player");
     m.mk("/player_list/player:0/.id");
     m("/player_list/player:0/.id") = "0001";
     // player 1 name
     m.mk("/player_list/player:0/name");
     m("/player_list/player:0/name") = "xterm-in-hate";
     // player 1 level
     m.mk("/player_list/player:0/level");
     m("/player_list/player:0/level") = "39";
     // player 1 class
     m.mk("/player_list/player:0/class");
     m("/player_list/player:0/class") = "berseker";
     // player 1 experience
     m.mk("/player_list/player:0/experience");
     m("/player_list/player:0/experience") = "8012";
     // player 1 position
     m.mk("/player_list/player:0/position");
     m.mk("/player_list/player:0/position/world");
     m("/player_list/player:0/position/world") = "earth";
     m.mk("/player_list/player:0/position/xcord");
     m("/player_list/player:0/position/xcord") = "111";
     m.mk("/player_list/player:0/position/ycord");
     m("/player_list/player:0/position/ycord") = "452";
     m.mk("/player_list/player:0/position/zcord");
     m("/player_list/player:0/position/zcord") = "37";
     m.mk("/player_list/player:0/position/xyangle");
     m("/player_list/player:0/position/xyangle") = "162";
     m.mk("/player_list/player:0/position/xzangle");
     m("/player_list/player:0/position/xzangle") = "-9";
     // player 1 health
     m.mk("/player_list/player:0/health");
     m("/player_list/player:0/health") = "120";
     // player 1 mana
     m.mk("/player_list/player:0/mana");
     m("/player_list/player:0/mana") = "270";
     // player 2
     m.mk("/player_list/player");
     m.mk("/player_list/player:1/.id");
     m("/player_list/player:1/.id") = "0002";
     // player 2 name
     m.mk("/player_list/player:1/name");
     m("/player_list/player:1/name") = "guest";
     // player 2 level
     m.mk("/player_list/player:1/level");
     m("/player_list/player:1/level") = "1";
     // player 2 class
     m.mk("/player_list/player:1/class");
     m("/player_list/player:1/class") = "paladin";
     // player 2 experience
     m.mk("/player_list/player:1/experience");
     m("/player_list/player:1/experience") = "0";
     // player 2 position
     m.mk("/player_list/player:1/position");
     m.mk("/player_list/player:1/position/world");
     m("/player_list/player:1/position/world") = "earth";
     m.mk("/player_list/player:1/position/xcord");
     m("/player_list/player:1/position/xcord") = "118";
     m.mk("/player_list/player:1/position/ycord");
     m("/player_list/player:1/position/ycord") = "493";
     m.mk("/player_list/player:1/position/zcord");
     m("/player_list/player:1/position/zcord") = "38";
     m.mk("/player_list/player:1/position/xyangle");
     m("/player_list/player:1/position/xyangle") = "25";
     m.mk("/player_list/player:1/position/xzangle");
     m("/player_list/player:1/position/xzangle") = "0";
     // player 2 health
     m.mk("/player_list/player:1/health");
     m("/player_list/player:1/health") = "50";
     // player 2 mana
     m.mk("/player_list/player:1/mana");
     m("/player_list/player:1/mana") = "22";
     // build XML file/stream 	 
     cout << root.build() << endl;
}	

/////////////////////////////////////////////////////////////////////////////
// CECI EST UN APPERCU DU CODE ZIPPE....
/////////////////////////////////////////////////////////////////////////////

Conclusion

Formalisme de t_xml_manip. Les noeuds/attributs XML sont manipulés comme un système de fichier. La notion de chemin est donc la clé de cette interface. Par exemple : "/racine/noeud" pointe vers le noeud 'noeud' appartenant à la racine 'racine'; "/racine/noeud/.attrib" pointe vers l'attribut 'attrib' appartenant au noeud 'noeud', appartenant à la racine 'racine'.

---

Je remercie Tom87@21 et BaBar60 qui m'ont soutenu pendant la première phase de développement de cette petite librairie. Merci également à l'ensemble des intervenant qui au travers de leur remarques et observation m'ont permis d'améliorer MinXL.

---

Je remercie aussi toutes les personnes qui, grace à leurs commentaires, ont permis à MinXL d'évoluer favorablement au fil du temps.

 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

20 mai 2005 03:18:31 :
20 mai 2005 : - Modification des inclusions (remarque steve_clamage), - Ajout d'une protection contre les inclusions multiples (remarque steve_clamage), - Ajout commentaires - Révision de la constness des fonctions membres de t_xml_manip, - Ajout d'une exception déclenchée lorsque le fichier XML passé en argument de t_xml_node::parse est de format incorrect.
20 mai 2005 03:23:35 :
20 mai 2005 : - Modification des inclusions (bis).
20 mai 2005 03:27:11 :
20 mai 2005 : - Mise en forme sur CodeS-SourceS.
21 mai 2005 14:10:28 :
21 mai 2005 : - Correction de namespace.
21 mai 2005 14:14:13 :
21 mai 2005 : - Correction du Zip.
21 mai 2005 22:41:00 :
21 main 2005 : - Ajout de la gestion des attributs dans t_xml_node, - Modification du 'build' permetant de transformer un t_xml_node en un fichier/flux XML avec attributs, - Ajouts de commentaires. TODO : Extraction des attributs à partir d'un fichier/flux XML -> 'parser' V1.1 à venir.
22 mai 2005 17:56:59 :
22 mai 2005 : - Nouvelle version : V1.1 ! Les attributs XML sont maintenant gérés correctement.
27 mai 2005 23:18:07 :
27 mai 2005 : - Visualisation/Création/Retrait des attributes via t_xml_manip (les attributs portent le préfixe '.'). - Ajout d'un exemple complet de création d'un fichie rXML à partir de t_xml_node.
27 mai 2005 23:24:46 :
27 mai 2005 : - Mise en forme sur CodeS-SourceS.
28 mai 2005 22:52:31 :
28 mai 2005 : - Amélioration de la classe t_xml_manip pour lire/écrire les attributs de manire simple. - Ajout d'un exemple complémentaire.
31 mai 2005 20:50:54 :
31 mai 2005 : - Modification de l'interface du parser/builder de t_xml_node (merci BaBar 60 pour ton aide).
14 juillet 2005 11:03:08 :
14 juillet 2005 : - Modification des prototypes de fonctions what() des exceptions MinXL (mise en conformité avec la lib C++ std). - Modification du 'parser' pour ignorer commentaires et prologue XML (modification suite au message de yAAm). - Attention : CVS SF n'est pas à jour (resynch prévue le 1er aout / je suis en vacances !!!).
16 juillet 2005 12:35:50 :
16 juillet 2005 : - Réécriture du parser avec formalisation de la machine a états (gain perf. ~10%, lisibilité/évolutivité fortement accrue). - Ajout du support de la syntaxe XML : "<tag/>" et "<tag att1="val" att2="val"/>" (demande Sabugo).
18 juillet 2005 13:45:25 :
18 juillet 2005 : - Amélioration du 'parser'. Support de l'encodage/décodage des caractères XML spéciaux. L'utilisation de &, ", CR, LR, TAB, <, et > dans la valeur d'un noeud XML ou dans la valeur d'un attribut XML est possible (norme XML 1.0).
19 juillet 2005 09:33:41 :
16 juillet 2005 : - Optimisation de la classe t_xml_node (ajout d'une fonction membre publique : last_inserted_child()). Le gain de rapidité, induit au moment de 'parser' un flux XML, est foudroyant (~500%).
11 août 2005 19:27:37 :
11 aout 2005 : - Compatibilité avec le compilateur VC6 (enfin!).
08 mai 2006 00:29:06 :
Correction d'un bug pour compilateur windows 2003 et supérieur.
29 février 2008 15:48:28 :
29-02-2008 : Correction d'une anomalie (segfault) intervenant lors de l'interprétation d'un fichier xml invalide. Le traitement d'une chaine formatée "&xxxx;" invalide génère maintenant une exception de "format xml invalide".
29 février 2008 15:50:49 :
29-02-2008 : Correction d'une anomalie (segfault) intervenant lors de l'interprétation d'un fichier xml invalide. Le traitement d'une chaine formatée "&xxxx;" invalide génère maintenant une exception de "format xml invalide".
16 mars 2008 09:15:49 :
- Modification des directives de précompilation, - Factorisation du code de "copy" et "move". - TODO : compatibilité basique de xml_manip vers Xpath. (remarques Christophe)

Commentaires et avis

signaler à un administrateur
Commentaire de luhtor le 19/05/2005 11:25:43

Très très bien, je vais l'utiliser. Par contre, bon c'est peut etre à moi de rajouter ces fonctions dans mon programme, j'aurais besoin des fonctions de conversion classique tel que To_Float(), To_Int() etc ... pour convertir les chaines.
Par exemple, utiliser ce qu'il donne sur ce site:
http://c.developpez.com/faq/cpp/?page=strings#STRINGS_convertform

"L'utilisation de istringstream permet de convertir une string en n'importe quel type pour lequel l'opérateur istream::operator >>() a été défini. Il est donc possible de créer une fonction générique de conversion d'une string en un autre type grâce à l'utilisation des templates :"

#include <sstream>
template<typename T>
bool from_string( const std::string & Str, T & Dest )
{
// créer un flux à partir de la chaîne donnée
std::istringstream iss( Str );
// tenter la conversion vers Dest
return iss >> Dest != 0; }

int main()
{
int dix; from_string( "10", dix );
}

Ca pourrait s'avérer pratique pour par exemple, enregistrer une matrice ou n'importe quel autre type.

En tout cas, merci pour cette source.