{"id":5675,"date":"2016-08-31T07:24:52","date_gmt":"2016-08-31T07:24:52","guid":{"rendered":"http:\/\/anthroponaute.fr\/blog-informatique\/?p=5675"},"modified":"2024-02-21T09:50:54","modified_gmt":"2024-02-21T09:50:54","slug":"apprendre-a-utiliser-tinyxml-pour-charger-vos-fichiers-xml","status":"publish","type":"post","link":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/?p=5675","title":{"rendered":"Apprendre \u00e0 utiliser TinyXML pour charger vos fichiers XML"},"content":{"rendered":"<p><a href=\"https:\/\/anthropoya.cluster014.ovh.net\/blog-informatique\/wp-content\/uploads\/2016\/08\/tinyxml.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone  wp-image-5676\" src=\"https:\/\/anthropoya.cluster014.ovh.net\/blog-informatique\/wp-content\/uploads\/2016\/08\/tinyxml.png\" alt=\"tinyxml\" width=\"327\" height=\"190\" srcset=\"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/wp-content\/uploads\/2016\/08\/tinyxml.png 473w, https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/wp-content\/uploads\/2016\/08\/tinyxml-300x174.png 300w\" sizes=\"(max-width: 327px) 100vw, 327px\" \/><\/a><\/p>\n<p><strong>Intro :<\/strong><\/p>\n<p>Parfois dans un programme ou un jeu vid\u00e9o, il est n\u00e9cessaire de <strong>charger des donn\u00e9es<\/strong> sous format <strong>XML<\/strong>. Par exemple pour un <strong>\u00e9diteur de sc\u00e8ne<\/strong> \/ monde, on peut vouloir <strong>charger les positions<\/strong> des entit\u00e9s directement depuis un fichier <em>Scene.xml<\/em> par exemple.<\/p>\n<p><strong>Pr\u00e9requis :<\/strong><\/p>\n<p>&#8211; Savoir lire du <em>C++<\/em><\/p>\n<p>&#8211; Savoir lire un <em>fichier XML<\/em><\/p>\n<p>&#8211; Savoir importer des <em>fichiers sources<\/em> dans Visual C++<\/p>\n<p><strong>Explications :<\/strong><\/p>\n<p>TinyXML est une toute<strong> petite librairie<\/strong> C++ permettant de charger et d&rsquo;analyser les donn\u00e9es stock\u00e9es dans un<strong> fichier XML<\/strong>. Elle est sous la licence Zlib (cela signifie que vous pouvez l&rsquo;utiliser pour n&rsquo;importe quoi !)<\/p>\n<p>D&rsquo;abord il vous faut<strong> t\u00e9l\u00e9charger les sources<\/strong> de TinyXML. La derni\u00e8re version \u00e0 la date d&rsquo;\u00e9criture de cet article est la version 2.<\/p>\n<p>Deux choix s&rsquo;offrent \u00e0 vous : soit d&rsquo;utiliser la <em>version 1<\/em> ; soit d&rsquo;utiliser la <em>version 2<\/em>.<\/p>\n<p>Les avantages de choisir la 2\u00e8me : meilleur gestion de la m\u00e9moire ; lecture plus rapide du fichier XML ; pas d&rsquo;utilisation de la STL.<\/p>\n<p>TinyXML charge compl\u00e8tement un fichier XML avec la m\u00e9thode <strong>LoadFile()<\/strong>&#8230; Il vous reste ensuite le soin d&rsquo;analyser votre fichier XML en fonction de son <strong>contenu<\/strong> en terme de <em>n\u0153uds<\/em>.<\/p>\n<p>On pr\u00e9cise que XML est l&rsquo;abr\u00e9viation de \u00ab\u00a0e<strong>X<\/strong>tensible <strong>M<\/strong>arkup <strong>L<\/strong>anguage\u00a0\u00bb. XML est un format pour<strong> stocker des donn\u00e9es<\/strong>, pas un langage de programmation !<br \/>\nCelles-ci sont \u00e9crites entre des balises ou sous forme d&rsquo;attributs, et l&rsquo;ensemble est \u00e9crit sous forme d&rsquo;un arbre.<\/p>\n<p>Voici la <strong>structure<\/strong> d&rsquo;un fichier XML :<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&amp;lt;?xml version=&amp;quot;1.0&amp;quot; ?&amp;gt;\r\n&amp;lt;root&amp;gt;\r\n\u00a0\u00a0\u00a0 &amp;lt;UnElement attribut1 =&amp;quot;une valeur&amp;quot; \/&amp;gt;\r\n\u00a0\u00a0\u00a0 &amp;lt;UnAutreElement attribut2 = &amp;quot;2&amp;quot; attribute3 = &amp;quot;3&amp;quot;&amp;gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &amp;lt;Element3 attribut4=&amp;quot;4&amp;quot; \/&amp;gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Du Texte !\r\n\u00a0\u00a0\u00a0 &amp;lt;\/UnAutreElement&amp;gt;\r\n&amp;lt;\/root&amp;gt;\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Il vous faut <strong>importer<\/strong> dans votre projet Visual C++ la librairie directement par l&rsquo;interm\u00e9diaire de ces fichiers :<\/p>\n<p style=\"padding-left: 30px;\"><strong>&#8211; tinystr.cpp<\/strong><br \/>\n<strong> &#8211; tinyxmlerror.cpp<\/strong><br \/>\n<strong> &#8211; tinystr.h<\/strong><br \/>\n<strong> &#8211; tinyxml.h<\/strong><br \/>\n<strong> &#8211; tinyxml.cpp<\/strong><br \/>\n<strong> &#8211; tinyxmlparser.cpp<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Dans votre fichier source .cpp utilisant TinyXML, il vous faudra \u00e9crire #include \u00ab\u00a0tinyxml.h\u00a0\u00bb en tant que fichier d&rsquo;en-t\u00eate !<\/p>\n<p>Vous pouvez d\u00e9finir le define <strong>#define TIXML_USE_STL<\/strong> pour <strong>activer <\/strong>l&rsquo;utilisation de la <strong>STL<\/strong> dans TinyXml.<\/p>\n<p>Sachez que TinyXML <strong>reconna\u00eet<\/strong> automatiquement <strong>l&rsquo;encodage<\/strong> utilis\u00e9 par le fichier \u00e0 charger (il n&rsquo;est pas n\u00e9cessaire de renseigner l&rsquo;attribut \u00ab\u00a0encoding\u00a0\u00bb).<\/p>\n<p>Commen\u00e7ons l&rsquo;analyse d&rsquo;un fichier quelconque :<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nTiXmlDocument doc;\r\nif(!doc.LoadFile(&amp;quot;Test.xml&amp;quot;))\r\n{\r\n\u00a0\u00a0\u00a0 std::cerr &amp;lt;&amp;lt; doc.ErrorDesc() &amp;lt;&amp;lt; std::endl;\r\n\u00a0\u00a0\u00a0 return FAILURE;\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Le fichier \u00ab\u00a0doc\u00a0\u00bb contient toutes les donn\u00e9es d&rsquo;analyse du fichier XML charg\u00e9.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nTiXmlElement* pRoot = doc.FirstChildElement();\r\nif (pRoot == nullptr)\r\n{\r\n\u00a0\u00a0\u00a0 std::cerr &amp;lt;&amp;lt; &amp;quot;Echec chargement du fichier. Aucun \u00e9l\u00e9ment racine.&amp;quot; &amp;lt;&amp;lt; std::endl;\r\n\u00a0\u00a0\u00a0 doc.Clear();\r\n\r\n\u00a0\u00a0\u00a0 return FAILURE;\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>La m\u00e9thode <strong>FirstChildElement()<\/strong> renvoie un pointeur vers un objet <strong>TinyXmlElement<\/strong> qui repr\u00e9sente le premier <em>n\u0153ud<\/em> du fichier XML en question. <strong>FirstChildElement()<\/strong> prend un param\u00e8tre une cha\u00eene de caract\u00e8res repr\u00e9sentant le nom du n\u0153ud en question.<\/p>\n<p>Une boucle permet d&rsquo;afficher tout les noms des \u00e9l\u00e9ments du fichier :<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nfor (TiXmlElement* pElem = pRoot-&amp;gt;FirstChildElement(); pElem != nullptr; pElem = pElem-&amp;gt;NextSiblingElement())\r\n{\r\n\u00a0\u00a0\u00a0 std::string elemName = pElem-&amp;gt;Value();\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Le principe est le suivant : on parcourt chaque n\u0153ud en <strong>extrayant de chaque<\/strong> n\u0153ud enfant les attributs qui nous int\u00e9ressent !<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n...\r\n\r\n[...La boucle...]\r\n\r\n\u00a0\u00a0\u00a0 const char* attr = nullptr;\r\n\r\n\u00a0\u00a0\u00a0 if (elemName == &amp;quot;UnElement&amp;quot;)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 attr = elem-&amp;gt;Attribute(&amp;quot;attribut1&amp;quot;);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (attr != nullptr)\r\n\u00a0\u00a0 \u00a0    {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0    \/\/ Faire le travail d&#039;analyse ici\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n\r\n[...Fin de boucle...]\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>La variable <strong><em>attr<\/em> <\/strong>repr\u00e9sente la <strong>valeur de l&rsquo;attribut<\/strong> en question. Si l&rsquo;attribut ne comporte pas le nom sp\u00e9cifi\u00e9. La m\u00e9thode <strong>Attribute(&#8230;)<\/strong> renvoie nullptr.<\/p>\n<p>On peut tester si le contenu d&rsquo;un n\u0153ud est du texte avec la m\u00e9thode <strong><em>elem-&gt;ToText()<\/em><\/strong>. Elle renvoie <strong>nullptr<\/strong> s&rsquo;il n&rsquo;y a pas de texte.<\/p>\n<p>Il peut \u00eatre utile d&rsquo;utiliser une structure de donn\u00e9es sp\u00e9cifique customis\u00e9e afin de stocker les donn\u00e9es lues depuis le fichier XML. Mais cela reste facultatif !<\/p>\n<p>On fini l&rsquo;analyse avec l&rsquo;appel de Clear() : doc.Clear();<\/p>\n<p>Pour faciliter le parcours des n\u0153uds, on peut utiliser ce qu&rsquo;on appelle des <em><strong>handles<\/strong><\/em>.<br \/>\nExemple :<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nTiXmlHandle hdl(&amp;amp;doc);\r\nTiXmlElement *elem = hdl.FirstChildElement().FirstChildElement().Element();\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>La m\u00e9thode <strong>QueryIntAttribute(&#8230;)<\/strong> permet d&rsquo;obtenir la valeur d&rsquo;un attribut sous forme de integer<\/p>\n<p>Voici la liste des classes de TinyXML format\u00e9e par <em>Doxygen<\/em> : http:\/\/www.grinninglizard.com\/tinyxmldocs\/annotated.html<\/p>\n<p><strong>R\u00e9sum\u00e9 :<\/strong><\/p>\n<p><strong>Simple<\/strong> et <strong>efficace<\/strong>, la petite librairie <em>TinyXML<\/em> facilitera vos chargement de donn\u00e9es sous format XML.<\/p>\n<p><strong>R\u00e9f\u00e9rences :<\/strong><\/p>\n<p>&#8211; http:\/\/www.dinomage.com\/2012\/01\/tutorial-using-tinyxml-part-1\/<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Intro : Parfois dans un programme ou un jeu vid\u00e9o, il est n\u00e9cessaire de charger des donn\u00e9es sous format XML. Par exemple pour un \u00e9diteur de sc\u00e8ne \/ monde, on peut vouloir charger les positions des entit\u00e9s directement depuis un fichier Scene.xml par exemple. Pr\u00e9requis : &#8211; Savoir lire du C++ &#8211; Savoir lire un [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[19],"tags":[],"_links":{"self":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts\/5675"}],"collection":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5675"}],"version-history":[{"count":24,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts\/5675\/revisions"}],"predecessor-version":[{"id":5974,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts\/5675\/revisions\/5974"}],"wp:attachment":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5675"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5675"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5675"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}