<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog IT Cobalt</title>
	<atom:link href="http://blog.itcobalt.ch/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.itcobalt.ch</link>
	<description>Open source, Linux, développement, sécurité, ...</description>
	<lastBuildDate>Thu, 30 Jul 2009 12:09:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Conception de votre base de données avec MySQL Workbench</title>
		<link>http://blog.itcobalt.ch/2009/07/30/conception-de-votre-base-de-donnees-avec-mysql-workbench/</link>
		<comments>http://blog.itcobalt.ch/2009/07/30/conception-de-votre-base-de-donnees-avec-mysql-workbench/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 12:09:37 +0000</pubDate>
		<dc:creator>Damien Zufferey</dc:creator>
				<category><![CDATA[Base de données]]></category>
		<category><![CDATA[modélisation]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://blog.itcobalt.ch/?p=241</guid>
		<description><![CDATA[Lorsque l&#8217;on bosse sur un projet qui contient plusieurs tables ayant des relations entre elles, il est agréable de disposer d&#8217;un logiciel permettant de concevoir son modèle des données ainsi que la possibilité d&#8217;y générer ensuite les tables automatiquement sur le SGBDR.
Pour ceux qui bossent avec MySQL, il existe depuis longtemps un outil gratuit s&#8217;appelant [...]]]></description>
			<content:encoded><![CDATA[<p>Lorsque l&#8217;on bosse sur un projet qui contient plusieurs tables ayant des relations entre elles, il est agréable de disposer d&#8217;un logiciel permettant de concevoir son modèle des données ainsi que la possibilité d&#8217;y générer ensuite les tables automatiquement sur le SGBDR.</p>
<p>Pour ceux qui bossent avec MySQL, il existe depuis longtemps un outil gratuit s&#8217;appelant DBDesigner 4 qui est développé par fabforce.net.</p>
<p>Michael G. Zinner, le concepteur de ce logiciel a rejoint la société MySQL, ce qui a donné naissance au nouveau produit MySQL Workbench, dont voici une capture d&#8217;écran ci-dessous.</p>
<p><a href="http://blog.itcobalt.ch/wp-content/uploads/2009/07/capturemysqlworkbench.png"><img class="aligncenter size-full wp-image-242" title="Capture d'écran de MySQL Workbench" src="http://blog.itcobalt.ch/wp-content/uploads/2009/07/capturemysqlworkbench.png" alt="Capture d'écran de MySQL Workbench" width="501" height="401" /></a></p>
<p>Ce logiciel a bien évolué et contient toutes les fonctionnalités que l&#8217;on attend d&#8217;un bon système de conception de bases de données. Cet outil spécialisé pour MySQL permet notamment de générer un script SQL pour y créer les tables. De plus, par la rétro-ingénierie sur des bases existantes, on peut extraire la structure et en donner une interprétation graphique.</p>
<p>Depuis la version 5.1 sortie le 30 juin 2009, le logiciel est devenu multiplateforme et est disponible désormais pour Windows, Linux et Mac.</p>
<p>En plus de la version open source (licence GPL), il existe une version commerciale payante qui comprend des fonctionnalités supplémentaires dans les domaines de la validation du schéma / modèle de données ainsi qu&#8217;au niveau de la documentation des tables et autres objets.</p>
<p>A essayer &#8230;</p>
<p>Site internet : <a title="MySQL Workbench" href="http://dev.mysql.com/workbench/" target="_blank">http://dev.mysql.com/workbench/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.itcobalt.ch/2009/07/30/conception-de-votre-base-de-donnees-avec-mysql-workbench/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Parser un fichier XML volumineux en C avec la Libxml2</title>
		<link>http://blog.itcobalt.ch/2009/05/24/parser-un-fichier-xml-volumineux-en-c-avec-la-libxml2/</link>
		<comments>http://blog.itcobalt.ch/2009/05/24/parser-un-fichier-xml-volumineux-en-c-avec-la-libxml2/#comments</comments>
		<pubDate>Sun, 24 May 2009 09:39:08 +0000</pubDate>
		<dc:creator>Damien Zufferey</dc:creator>
				<category><![CDATA[Développement C/C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[libxml2]]></category>
		<category><![CDATA[sax]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.itcobalt.ch/?p=65</guid>
		<description><![CDATA[Dans le cadre d&#8217;un projet, j&#8217;ai plusieurs fichiers XML volumineux (plusieurs Go) que je dois parser pour en extraire des données à insérer en base de données. En fait, ces fichiers XML contiennent des articles d&#8217;un site de commerce électronique. Par un programme d&#8217;affiliation, je dois faire apparaître certains de ces articles sur un site [...]]]></description>
			<content:encoded><![CDATA[<p>Dans le cadre d&#8217;un projet, j&#8217;ai plusieurs fichiers XML volumineux (plusieurs Go) que je dois parser pour en extraire des données à insérer en base de données. En fait, ces fichiers XML contiennent des articles d&#8217;un site de commerce électronique. Par un programme d&#8217;affiliation, je dois faire apparaître certains de ces articles sur un site web.</p>
<p>Lorsque que l&#8217;on souhaite parser du XML, on a principalement le choix entre 2 méthodes différentes. On a DOM (Document Object Model) qui va charger l&#8217;intégralité d&#8217;un document XML en mémoire sous forme d&#8217;un arbre, ce qui rend aisé la manipulation du document. Cependant avec un fichier XML volumineux cette méthode n&#8217;est pas possible. Dans ce cas, on va utiliser la méthode SAX (Simple API for XML). Avec SAX on a une analyse événementielle, cela veut dire que le document XML est analysé au fur et à mesure et selon le type de l&#8217;élément rencontré (balise, commentaire ou texte), une fonction de rappel (callback) est appelée pour traiter l&#8217;élément concerné. Donc SAX en utilisant moins de mémoire est parfait pour extraire des données de grands fichiers XML.</p>
<p>Par le passé, j&#8217;utilisais Java avec <a title="Xerces2 Java Parser" href="http://xerces.apache.org/xerces2-j/" target="_blank">Xerces</a> mais pour un souci de performance (le plus vite possible en utilisant le moins de mémoire) je me suis orienté sur des implémentations en C. J&#8217;ai découvert deux librairies open source : <a title="The Expat XML Parser" href="http://expat.sourceforge.net/" target="_blank">Expat</a> et <a title="The XML C parser and toolkit of Gnome" href="http://xmlsoft.org/" target="_blank">Libxml2</a>. Comme il faut faire un choix, j&#8217;ai opté pour la Libxml2. Il s&#8217;agit d&#8217;une puissante boîte à outils XML développée dans le cadre du projet Gnome, mais elle est tout à fait utilisable en dehors de celui-ci, elle n&#8217;a pas de dépendance et elle se compile simplement avec l&#8217;API ANSI C.</p>
<p><span id="more-65"></span></p>
<p>Ci-dessous je vais présenter un cas concret à l&#8217;aide de la Libxml2 (SAX) d&#8217;un programme qui permet de parser un fichier XML pour en afficher le contenu souhaité. En parcourant le code source de ce programme, j&#8217;expliquerai au fur et à mesure les fonctions utilisées de l&#8217;API Libxml2.</p>
<p>Vous pouvez télécharger une archive contenant le fichier source c, le Makefile ainsi que le fichier XML exemple : <a href="http://blog.itcobalt.ch/wp-content/uploads/2009/05/xmlsaxparsertar.gz">xmlsaxparser.tar.gz</a>.</p>
<p><strong>&#8211; Fichier &#8216;articles.xml&#8217; &#8211;</strong></p>
<p>Voici comment est structuré le fichier XML des articles :</p>
<pre><span style="color: #800080;">&lt;?xml</span> <span style="color: #3366ff;">version=</span><span style="color: #ff00ff;">"1.0"</span> <span style="color: #3366ff;">encoding=</span><span style="color: #ff00ff;">"iso-8859-1"</span><span style="color: #800080;">?&gt;</span>
<span style="color: #008000;">&lt;articles&gt;</span>
   <span style="color: #008000;"> &lt;article&gt;</span>
        <span style="color: #008000;">&lt;id&gt;</span><span style="color: #000000;">173968</span><span style="color: #008000;">&lt;/id&gt;</span>
        <span style="color: #008000;">&lt;name&gt;</span><span style="color: #800080;">&lt;![CDATA[</span><span style="color: #000000;">The Rock</span><span style="color: #800080;">]]&gt;</span><span style="color: #008000;">&lt;/name&gt;</span>
       <span style="color: #008000;"> &lt;description&gt;</span><span style="color: #800080;">&lt;![CDATA[</span><span style="color: #000000;">a film of the year 1996</span><span style="color: #800080;">]]&gt;</span><span style="color: #008000;">&lt;/description&gt;</span>
        <span style="color: #008000;">&lt;category&gt;</span><span style="color: #800080;">&lt;![CDATA[</span><span style="color: #000000;">DVD</span> <span style="color: #000000;">Movie</span><span style="color: #800080;">]]&gt;</span><span style="color: #008000;">&lt;/category&gt;</span>
        <span style="color: #008000;">&lt;price&gt;</span><span style="color: #000000;">11.95</span><span style="color: #008000;">&lt;/price&gt;</span>
       <span style="color: #008000;"> &lt;url&gt;</span><span style="color: #800080;">&lt;![CDATA[</span><span style="color: #000000;">http://abc.domain.ext/showArticle?id=173968</span><span style="color: #800080;">]]&gt;</span><span style="color: #008000;">&lt;/url&gt;</span>
       <span style="color: #008000;"> &lt;availability&gt;</span><span style="color: #000000;">141</span><span style="color: #008000;">&lt;/availability&gt;</span>
        <span style="color: #008000;">&lt;condition&gt;</span><span style="color: #000000;">used</span><span style="color: #008000;">&lt;/condition&gt;</span>
    <span style="color: #008000;">&lt;/article&gt;</span>
    <span style="color: #000000;">[...]</span>
<span style="color: #008000;">&lt;/articles&gt;</span></pre>
<p>Remarquez l&#8217;encodage du fichier en ISO-8859-1 (encodage par défaut des fichiers que je reçois dans le cadre du projet), mais de préférence utilisez si possible UFT-8 (unicode) car la Libxml2 travaille dans cet encodage internement.</p>
<p><strong>&#8211; Fichier &#8216;xmlsaxparser.c&#8217; &#8211;</strong></p>
<p>(Seulement les lignes qui me semblent importantes sont présentées ci-dessous, pour l&#8217;intégralité se référer au fichier fourni dans l&#8217;archive téléchargeable ci-dessus.)</p>
<p>Inclure la ligne suivante afin de pouvoir accéder aux fonctions de la Libxml2 :</p>
<pre><span style="color: #008000;">#include</span> <span style="color: #ff9900;">&lt;libxml2/libxml/parser.h&gt;
</span></pre>
<p>Créer une structure pour stocker temporairement les champs d&#8217;un article :</p>
<pre><span style="color: #008000;"><span style="color: #0000ff;">struct</span> <span style="color: #000000;">article {</span>
    <span style="color: #0000ff;">char</span> id<span style="color: #000000;">[<span style="color: #3366ff;">ID_SIZE</span> + 1];</span>
    <span style="color: #0000ff;">char</span> name<span style="color: #000000;">[<span style="color: #3366ff;">NAME_SIZE</span> + 1];</span>
    <span style="color: #0000ff;">char</span> category<span style="color: #000000;">[<span style="color: #3366ff;">CATEGORY_SIZE</span> + 1];</span>
    <span style="color: #0000ff;">char</span> price<span style="color: #000000;">[<span style="color: #3366ff;">PRICE_SIZE</span> + 1];</span>
    <span style="color: #0000ff;">char</span> url<span style="color: #000000;">[<span style="color: #3366ff;">URL_SIZE</span> + 1];</span>
    <span style="color: #0000ff;">char</span> availability<span style="color: #000000;">[<span style="color: #3366ff;">AVAILABILITY_SIZE</span> + 1];</span>
    <span style="color: #0000ff;">char</span> condition<span style="color: #000000;">[<span style="color: #3366ff;">CONDITION_SIZE</span> + 1];</span>
<span style="color: #000000;">} article;</span></span></pre>
<p>Créer une fonction (qui nous sera utile plus tard) permettant de copier dans le champ correspondant de la structure article, le texte renvoyé par le parseur :</p>
<pre><span style="color: #008000;"><span style="color: #0000ff;">void <strong><span style="color: #000000;">writeFieldArticle</span></strong><span style="color: #000000;">(</span>char <span style="color: #000000;">*articleField,</span> int <span style="color: #000000;">articleSize,</span> const <span style="color: #000000;">xmlChar *ch,</span>
        int <span style="color: #000000;">len) {</span>
    int <span style="color: #000000;">nbCharsConsumed = len;</span>

    <span style="color: #808080;">/* I want text is encoded in ISO-8859-1 */</span>
    <span style="color: #000000;">UTF8Toisolat1(articleField, &amp;articleSize, ch, &amp;nbCharsConsumed);</span>

    <span style="color: #808080;">/* Detect, no enough space in articleField */</span>
    if<span style="color: #000000;">(nbCharsConsumed != len) {</span>
        <span style="color: #000000;">fprintf(</span><span style="color: #3366ff;">stderr</span><span style="color: #000000;">,</span><span style="color: #ff9900;">"ERROR: Not enough space to write %d characters\n\n"</span><span style="color: #000000;">,</span>
                <span style="color: #000000;">len);</span>
      <span style="color: #000000;">  fprintf(</span><span style="color: #3366ff;">stderr</span><span style="color: #000000;">,</span> <span style="color: #ff9900;">"Content to write (first %d characters) : \n\n%s\n"</span><span style="color: #000000;">,</span>
                <span style="color: #000000;">len, ch);</span>
      <span style="color: #000000;">  exit (</span><span style="color: #3366ff;">EXIT_FAILURE</span><span style="color: #000000;">);</span>
   <span style="color: #000000;"> }</span>

    <span style="color: #000000;">articleField[articleSize] = </span><span style="color: #ff9900;">'\0'</span><span style="color: #000000;">;</span>
  <span style="color: #000000;">  xmlTag = IGNORE;
}
</span></span></span></pre>
<p>Cette fonction a comme paramètres : un pointeur vers la chaîne de caractères où il faut écrire, le nombre de caractères effectifs (le caractère NULL de terminaison est déjà pris en compte) que peut contenir cette chaîne de caractères, la chaîne de caractères contenant le texte renvoyé par le parseur, la longueur de cette chaîne de caractères. Notez le type &#8216;xmlChar&#8217;, il s&#8217;agit d&#8217;un simple char non-signé et la chaîne de caractères est encodée en UTF-8. Donc, même si l&#8217;API fournit des fonctions spécialisées (ex: xmlStrcmp) pour la manipulation des chaînes de caractères, on peut tout à fait utiliser aussi les fonctions standard string  (string.h).</p>
<p>La fonction &#8216;UTF8Toisolat1&#8242; permet de convertir la string en ISO-8859-1 et par la même occasion de la copier dans le champ correspondant de notre structure article. Après l&#8217;exécution, l&#8217;argument deux contiendra le nombre d&#8217;octets écrit et l&#8217;argument quatre, le nombre d&#8217;octets consommé. A la ligne suivante, un test permet de détecter les cas où il n&#8217;y a pas assez de place pour accueillir le texte du parseur. Finalement, on n&#8217;oublie pas d&#8217;écrire le caractère NULL de terminaison. (Si vous souhaitez travailler en UTF-8, utilisez la fonction &#8217;strncpy&#8217; pour copier &#8216;ch&#8217; dans &#8216;articleField&#8217;.)</p>
<p>La fonction suivante est appelée à chaque ouverture d&#8217;une balise XML :</p>
<pre><span style="color: #008000;"><span style="color: #0000ff;">void <span style="color: #000000;"><strong>saxHandlerStartElement</strong>(</span>void <span style="color: #000000;">*ctx,</span> const <span style="color: #000000;">xmlChar *fullname,</span>
        const <span style="color: #000000;">xmlChar **atts) {</span>
    <span style="color: #808080;">/* New product to parse therefore reset fields */</span>
    if <span style="color: #000000;">(!strcmp(fullname, </span><span style="color: #ff9900;">"article"</span><span style="color: #000000;">)) {</span>
        <span style="color: #000000;">article.</span><span style="color: #008000;">id</span><span style="color: #000000;">[0] =</span> <span style="color: #ff9900;">'\0'</span><span style="color: #000000;">;</span>
        <span style="color: #000000;">article.</span><span style="color: #008000;">name</span><span style="color: #000000;">[0] =</span> <span style="color: #ff9900;">'\0'</span><span style="color: #000000;">;</span>
        <span style="color: #000000;">article.</span><span style="color: #008000;">category</span><span style="color: #000000;">[0] = </span><span style="color: #ff9900;">'\0'</span><span style="color: #000000;">;</span>
        <span style="color: #000000;">article.</span><span style="color: #008000;">price</span><span style="color: #000000;">[0] = </span><span style="color: #ff9900;">'\0'</span><span style="color: #000000;">;</span>
        <span style="color: #000000;">article.</span><span style="color: #008000;">url</span><span style="color: #000000;">[0] = </span><span style="color: #ff9900;">'\0'</span><span style="color: #000000;">;</span>
        <span style="color: #000000;">article.</span><span style="color: #008000;">availability</span><span style="color: #000000;">[0] =</span> <span style="color: #ff9900;">'\0'</span><span style="color: #000000;">;</span>
       <span style="color: #000000;"> article.</span><span style="color: #008000;">condition</span><span style="color: #000000;">[0] = </span><span style="color: #ff9900;">'\0'</span><span style="color: #000000;">;</span>
        <span style="color: #000000;">xmlTag = IGNORE;</span>
    <span style="color: #000000;">}</span> else if<span style="color: #000000;">(!strcmp(fullname,</span> <span style="color: #ff9900;">"id"</span><span style="color: #000000;">)) {</span>
       <span style="color: #000000;"> xmlTag = ID;
    } [...]</span></span></span></pre>
<p>Le premier argument de la fonction est un pointeur vers des données &laquo;&nbsp;utilisateur&nbsp;&raquo;, ce n&#8217;est pas utilisé dans cet exemple, mais on aurait très bien pu passer de cette façon la structure article. Les deux autres arguments sont le nom de la balise ouvrante rencontrée et ses attributs.</p>
<p>Dans cette fonction, on va simplement tester où on est au niveau de la structure du fichier XML et attribuer à &#8216;xmlTag&#8217;, la valeur correspondante. Remarquez qu&#8217;à chaque ouverture de la balise article, on &laquo;&nbsp;reset&nbsp;&raquo; les champs de notre structure étant donné que l&#8217;on procède à l&#8217;analyse d&#8217;un nouvel article.</p>
<p>La fonction suivante est appelée lorsque du texte est disponible entre une balise ouvrante et fermante :</p>
<pre><span style="color: #008000;"><span style="color: #0000ff;">void <span style="color: #000000;"><strong>saxHandlerCharacters</strong>(</span>void <span style="color: #000000;">*ctx,</span> const <span style="color: #000000;">xmlChar *ch,</span> int <span style="color: #000000;">len) {</span>
    switch <span style="color: #000000;">(xmlTag) {</span>
        case <span style="color: #000000;">IGNORE:</span>
            break<span style="color: #000000;">;</span>

        case <span style="color: #000000;">ID:</span>
           <span style="color: #000000;"> writeFieldArticle(article.</span><span style="color: #008000;">id</span><span style="color: #000000;">,</span> <span style="color: #3366ff;">ID_SIZE</span><span style="color: #000000;">, ch, len);</span>
            break<span style="color: #000000;">;

        [...]</span></span></span></pre>
<p>L&#8217;argument &#8216;*ch&#8217; est un pointeur vers le texte renvoyé par le parseur. Pour les balises dont on souhaite récupérer leur contenu, on appelle la fonction &#8216;writeFieldArticle&#8217; que l&#8217;on a créée précédemment.</p>
<p>La fonction suivante est appelée lorsque du texte est disponible entre une balise ouvrante et fermante, mais cette fois-ci lorsque l&#8217;on a à faire à des blocks CDATA :</p>
<pre><span style="color: #008000;"><span style="color: #0000ff;">void <span style="color: #000000;"><strong>saxHandlerCdataBlock</strong>(</span>void <span style="color: #000000;">*ctx,</span> const <span style="color: #000000;">xmlChar *ch,</span> int <span style="color: #000000;">len) {
    [...]
</span></span></span></pre>
<p>Au niveau du fonctionnement, c&#8217;est identique à la fonction précédente.</p>
<p>La fonction suivante est appelée lorsque une fermeture de balise XML est rencontrée :</p>
<pre><span style="color: #008000;"><span style="color: #0000ff;">void <span style="color: #000000;"><strong>saxHandlerEndElement</strong>(</span>void <span style="color: #000000;">*ctx,</span> const <span style="color: #000000;">xmlChar *name) {</span>
   <span style="color: #808080;"> /* An article was parsed. */</span>
    if <span style="color: #000000;">(!xmlStrcmp(name,</span> <span style="color: #ff9900;">"article"</span><span style="color: #000000;">)) {</span>
        <span style="color: #808080;">/* Write to standard output */</span>
        <span style="color: #000000;">printf(</span><span style="color: #ff9900;">"%s\t%s\t%s\t%s\t%s\t%s\t%s\n"</span><span style="color: #000000;">,</span>
                <span style="color: #000000;">article.</span><span style="color: #008000;">id</span><span style="color: #000000;">,</span> <span style="color: #000000;">article.</span><span style="color: #008000;">name</span><span style="color: #000000;">,</span> <span style="color: #000000;">article.</span><span style="color: #008000;">category</span><span style="color: #000000;">,</span> <span style="color: #000000;">article.</span><span style="color: #008000;">price</span><span style="color: #000000;">,</span>
                <span style="color: #000000;">article.</span><span style="color: #008000;">url</span><span style="color: #000000;">,</span> <span style="color: #000000;">article.</span><span style="color: #008000;">availability</span><span style="color: #000000;">,</span> <span style="color: #000000;">article.</span><span style="color: #008000;">condition</span><span style="color: #000000;">);</span>
<span style="color: #000000;">    }
}</span></span></span></pre>
<p>Si la balise fermante est article, cela veut dire que l&#8217;on a fini le parsing d&#8217;un article. Il est simplement afficher sur la sortie standard sur une ligne, les champs séparés par des tabulations. Le code peut être adapté, par exemple pour envoyer la structure article à une fonction responsable de l&#8217;insérer en base de données.</p>
<p>Voici maintenant comment initialiser le parseur pour ensuite le lancer :</p>
<pre><span style="color: #008000;"><span style="color: #0000ff;"><span style="color: #000000;">xmlSAXHandler saxHandler  = { 0 };
saxHandler.startElement = saxHandlerStartElement;
saxHandler.endElement = saxHandlerEndElement;
saxHandler.characters = saxHandlerCharacters;
saxHandler.cdataBlock = saxHandlerCdataBlock;</span>

<span style="color: #808080;">/* Start the parser */</span>
if<span style="color: #000000;"> (xmlSAXUserParseFile(&amp;saxHandler, </span><span style="color: #3366ff;">NULL</span><span style="color: #000000;">, xmlFilePath) != 0) {</span>
    <span style="color: #000000;">fprintf(</span><span style="color: #3366ff;">stderr</span><span style="color: #000000;">,</span>
          <span style="color: #ff9900;">  "ERROR : Error encountered during parsing of the XML file.\n"</span><span style="color: #000000;">);</span>
    return <span style="color: #000000;">(</span><span style="color: #3366ff;">EXIT_FAILURE</span><span style="color: #000000;">);</span>
<span style="color: #000000;">}</span></span></span></pre>
<p>La structure &#8216;xmlSAXHandler&#8217; contient des pointeurs sur des fonctions de rappel responsables de traiter les événements qui surviennent durant le parsing du document XML. On commence par définir à NULL tous les pointeurs de fonction pour éviter des appels indéfinis se soldant par &laquo;&nbsp;segmentation fault&nbsp;&raquo;. Puis on attribue pour les quatre fonctions de rappel (callback) ci-dessus, la correspondance avec le pointeur de fonction de la structure &#8216;xmlSAXHandler&#8217;. Et finalement on démarre le parseur en passant comme arguments : l&#8217;adresse de notre structure &#8216;xmlSAXHandler&#8217;, NULL pour préciser que l&#8217;on n&#8217;a pas de données &laquo;&nbsp;utilisateur&nbsp;&raquo; à transmettre aux fonctions de rappel et le dernier argument est le nom du fichier XML.</p>
<p><strong>– Fichier ‘Makefile’ –</strong></p>
<p>Voici le fichier Makefile que l&#8217;on peut utiliser pour compiler notre petit programme :</p>
<pre><span style="color: #008000;"><span style="color: #0000ff;"><span style="color: #000000;">CC = gcc
CFLAGS = `xml2-config --cflags`
LDFLAGS = `xml2-config --libs`
EXEC = xmlsaxparser

all: <span style="color: #008000;">$(EXEC)</span>

xmlsaxparser: xmlsaxparser.o
{TAB}<span style="color: #008000;">$(CC)</span> -o xmlsaxparser xmlsaxparser.o <span style="color: #008000;">$(LDFLAGS)</span>

xmlsaxparser.o: xmlsaxparser.c
{TAB}<span style="color: #008000;">$(CC)</span> -o xmlsaxparser.o -c xmlsaxparser.c <span style="color: #008000;">$(CFLAGS)</span>

clean:
{TAB}rm -rf *.o

mrproper: clean
{TAB}rm -rf <span style="color: #008000;">$(EXEC)
</span></span></span></span></pre>
<p>(Remplacez ci-dessus les {TAB} par des tabulations.)</p>
<p>Ce Makefile permet de compiler les sources sur un environnement de type UNIX comme Linux par exemple. Pour les autres systèmes d&#8217;exploitation (Windows, &#8230;), il faudra certainement faire quelques petites adaptations. Cependant il faut remarquer que la Libxml2 est extrêmement portable et donc cet exemple devrait compiler &laquo;&nbsp;partout&nbsp;&raquo;.</p>
<p>Remarquez dans ce Makefile, les deux appels à &#8216;xml2-config&#8217;, une fois pour optenir le chemin vers les fichiers d&#8217;inclusion et l&#8217;autre fois pour obtenir la librairie (libxml2) devant être liée lors de l&#8217;édition des liens.</p>
<p><strong>– Installation des outils, compilation et exécution du programme –</strong></p>
<p>Ayant développé ce petit exemple sur Ubuntu, l&#8217;installation des outils et la compilation sont basés sur cet OS mais tout ceci devrait être adaptable facilement à d&#8217;autres systèmes.</p>
<p>Sur Ubuntu, lancez un terminal et tapez ces lignes pour installer le kit de compilation et la librairie Libxml2 avec ces fichiers nécessaires pour le développement :</p>
<pre><span style="color: #008000;"><span style="color: #0000ff;"><span style="color: #000000;">sudo apt-get install build-essential libxml2 libxml2-dev
</span></span></span></pre>
<p>Ensuite pour compiler notre programme, il suffit d&#8217;aller dans le répertoire où se trouvent les sources et saisir les 2 commandes suivantes :</p>
<pre><span style="color: #008000;"><span style="color: #0000ff;"><span style="color: #000000;">make clean
make
</span></span></span></pre>
<p>La première commande nettoyera les éventuels restes d&#8217;anciennes compilations et la deuxième lancera la compilation.</p>
<p>Il reste plus qu&#8217;à exécuter le programme :</p>
<pre><span style="color: #008000;"><span style="color: #0000ff;"><span style="color: #000000;">./xmlsaxparser articles.xml
</span></span></span></pre>
<p>Si tout se passe bien, les quatre articles du fichier XML devraient s&#8217;afficher.<br />
(Attention le texte en sortie est encodé en ISO-8859-1, donc il faut éventuellement changer le paramètre d&#8217;encodage du terminal pour avoir un affichage correcte des caractères caractéristiques de la langue française.)</p>
<p><strong>– Ressources et suite &#8230; –</strong></p>
<p>Pour tout ce qui concerne la Libxml2 (documentation de l&#8217;API, download, &#8230;), le site officiel est : <a title="The XML C parser and toolkit of Gnome" href="http://xmlsoft.org" target="_blank">http://xmlsoft.org</a>.</p>
<p>Si vous cherchez un très bon tutoriel en français sur l&#8217;ensemble de l&#8217;API Libxml2 SAX et autres, c&#8217;est ici : <a title="Utilisation de la bibliothèque libxml2 en C" href="http://julp.developpez.com/c/libxml2" target="_blank">http://julp.developpez.com/c/libxml2</a>.</p>
<p>Dans un prochain billet, je vais présenter une solution simple pour insérer à grande vitesse le contenu extrait du fichier XML dans MySQL.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.itcobalt.ch/2009/05/24/parser-un-fichier-xml-volumineux-en-c-avec-la-libxml2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Récupérer l&#8217;icône de notification de mises à jour sous Ubuntu 9.04</title>
		<link>http://blog.itcobalt.ch/2009/05/04/recuperer-l-icone-de-notification-de-mises-a-jour-sous-ubuntu-9-04/</link>
		<comments>http://blog.itcobalt.ch/2009/05/04/recuperer-l-icone-de-notification-de-mises-a-jour-sous-ubuntu-9-04/#comments</comments>
		<pubDate>Mon, 04 May 2009 13:34:21 +0000</pubDate>
		<dc:creator>Damien Zufferey</dc:creator>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[update]]></category>

		<guid isPermaLink="false">http://blog.itcobalt.ch/?p=16</guid>
		<description><![CDATA[Avec la sortie de la nouvelle version de Ubuntu 9.04 (Jaunty Jackalope), l&#8217;icône de notification de mises à jour qui apparaissait dans la zone de notifications (System Tray) a disparu. Le nouveau comportement est d&#8217;ouvrir directement le gestionnaire de mises à jour pour &#171;&#160;forcer&#160;&#187; l&#8217;utilisateur a effectuer l&#8217;update le plus vite possible.
Pour avoir le comportement [...]]]></description>
			<content:encoded><![CDATA[<p>Avec la sortie de la nouvelle version de Ubuntu 9.04 (Jaunty Jackalope), l&#8217;icône de notification de mises à jour qui apparaissait dans la zone de notifications (System Tray) a disparu. Le nouveau comportement est d&#8217;ouvrir directement le gestionnaire de mises à jour pour &laquo;&nbsp;forcer&nbsp;&raquo; l&#8217;utilisateur a effectuer l&#8217;update le plus vite possible.</p>
<p>Pour avoir le comportement par défaut de l&#8217;ancienne version et ainsi récupérer l&#8217;icône de notification de mises à jour, il suffit de taper cette commande dans le Terminal :</p>
<p><code>gconftool --set --type bool /apps/update-notifier/auto_launch false</code></p>
<p>Cette commande va simplement inscrire la valeur booléenne false pour la clé &#8216;/apps/update-notifier/auto_launch&#8217; du système de configuration GConf.</p>
<h5><strong>Méthode graphique</strong></h5>
<p>Pour ceux qui sont allergiques à la console, on peut changer la configuration graphiquement.</p>
<p>Pour celà, on va utliser l&#8217;Editeur de configuration de Gnome (qui ressemble à la très connue base de registre de Windows <img src='http://blog.itcobalt.ch/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p>Premièrement on va modifier le menu &#8216;Applications&#8217; afin d&#8217;y rajouter un lien vers  l&#8217;Editeur de configuration (gconf-editor). Allez dans &#8216;Système&#8217; puis &#8216;Préférences&#8217; et &#8216;Menu principal&#8217;. Cochez l&#8217;élément &#8216;Editeur de configuration&#8217; du sous-menu &#8216;Outils système&#8217; comme dans la capture d&#8217;écran ci-dessous.</p>
<p><img class="alignnone size-full wp-image-50" title="Editeur du menu principal" src="http://blog.itcobalt.ch/wp-content/uploads/2009/05/screen_menu-editor.png" alt="Editeur du menu principal" width="685" height="560" /></p>
<p>Maintenant que l&#8217;Editeur de configuration est disponible via le menu principal, on peut l&#8217;ouvir et décocher la clé &#8216;/apps/update-notifier/auto_launch&#8217; comme dans la capture d&#8217;écran ci-dessous.</p>
<p><img class="alignnone size-full wp-image-56" title="Editeur de configuration" src="http://blog.itcobalt.ch/wp-content/uploads/2009/05/screen_gconf-editor.png" alt="Editeur de configuration" width="707" height="577" /></p>
<p>Voilà, au prochain lancement de votre session, l&#8217;icône de notification de mises à jour réapparaitra lorsque des updates seront disponibles. (Pour éviter de devoir redémarrer votre session, vous pouvez tuer le processus &#8216;update-notifier&#8217; et le relancer.)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.itcobalt.ch/2009/05/04/recuperer-l-icone-de-notification-de-mises-a-jour-sous-ubuntu-9-04/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tester en ligne son site sur plusieurs navigateurs</title>
		<link>http://blog.itcobalt.ch/2009/05/01/tester-en-ligne-son-site-sur-plusieurs-navigateurs/</link>
		<comments>http://blog.itcobalt.ch/2009/05/01/tester-en-ligne-son-site-sur-plusieurs-navigateurs/#comments</comments>
		<pubDate>Fri, 01 May 2009 17:39:07 +0000</pubDate>
		<dc:creator>Damien Zufferey</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[navigateur]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.itcobalt.ch/?p=11</guid>
		<description><![CDATA[Comme chaque navigateur web a sa façon (certains sont plus tordus que d&#8217;autres&#8230;   ) d&#8217;interpréter le HTML et les CSS, lorsque que l&#8217;on développe un site qui doit s&#8217;afficher correctement, on est obligé de tester le rendu un à un sur chaque navigateur / système d&#8217;exploitation.
Comme je travaille principalement sous Linux, j&#8217;ai besoin [...]]]></description>
			<content:encoded><![CDATA[<p>Comme chaque navigateur web a sa façon (certains sont plus tordus que d&#8217;autres&#8230; <img src='http://blog.itcobalt.ch/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) d&#8217;interpréter le HTML et les CSS, lorsque que l&#8217;on développe un site qui doit s&#8217;afficher correctement, on est obligé de tester le rendu un à un sur chaque navigateur / système d&#8217;exploitation.</p>
<p>Comme je travaille principalement sous Linux, j&#8217;ai besoin d&#8217;une machine virtuelle avec Windows pour tester mes développements sur les différentes versions de IE.</p>
<p>Il est aussi possible d&#8217;avoir recours à des services en ligne pour ce genre de tâche :</p>
<ul>
<li><a href="http://browsershots.org" target="_blank">http://browsershots.org</a> &gt; permet de tester son site sur plus de 50 navigateurs différents et de versions différentes sous Windows, Mac, Linux et BSD. Malheureusement le rendu n&#8217;est pas immédiat, le traitement est mis dans une file d&#8217;attente et il faut parfois attendre plus de 60 min !</li>
<li><a href="http://ipinfo.info/netrenderer" target="_blank">http://ipinfo.info/netrenderer</a> &gt; permet un rendu &laquo;&nbsp;instantané&nbsp;&raquo; mais limité aux navigateurs de la famille IE.</li>
</ul>
<p>Même si ces outils en ligne sont pratiques pour ce qui concerne le rendu HTML / CSS, difficile de tester les fonctionnalités faisant usage de JavaScript.</p>
<p>Est-ce qu&#8217;il y a d&#8217;autres solutions intéressantes sur le web ?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.itcobalt.ch/2009/05/01/tester-en-ligne-son-site-sur-plusieurs-navigateurs/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ouverture du Blog</title>
		<link>http://blog.itcobalt.ch/2009/05/01/ouverture-du-blog/</link>
		<comments>http://blog.itcobalt.ch/2009/05/01/ouverture-du-blog/#comments</comments>
		<pubDate>Fri, 01 May 2009 15:49:14 +0000</pubDate>
		<dc:creator>Damien Zufferey</dc:creator>
				<category><![CDATA[Général]]></category>

		<guid isPermaLink="false">http://blog.itcobalt.ch/?p=8</guid>
		<description><![CDATA[Hello à tous,
Cela faisait déjà un moment que je projetais d&#8217;ouvrir un blog traitant de divers sujets IT comme l&#8217;Open source, Linux,  le développement ou encore la sécurité informatique.
Dans mes activités de développement ou d&#8217;administration système, il m&#8217;est souvent arrivé de trouver les solutions à mes problèmes en cherchant sur le web ou simplement soi-même [...]]]></description>
			<content:encoded><![CDATA[<p>Hello à tous,</p>
<p>Cela faisait déjà un moment que je projetais d&#8217;ouvrir un blog traitant de divers sujets IT comme l&#8217;Open source, Linux,  le développement ou encore la sécurité informatique.</p>
<p>Dans mes activités de développement ou d&#8217;administration système, il m&#8217;est souvent arrivé de trouver les solutions à mes problèmes en cherchant sur le web ou simplement soi-même après de longues expérimentations. N&#8217;étant pas forcément toujours un champion de l&#8217;ordre, je rédigeais quelques notes sur papier ou dans un document informatisé, la démarche à suivre pour régler tel ou tel problème. Après quelque temps, par exemple 6 mois plus tard, on souhaite à nouveau configurer tel système sur un serveur et oups!, après de multiples recherches infructueuses un peu partout dans ses documents, on se rend compte qu&#8217;on avait peut-être même pas pris de notes et qu&#8217;il sera nécessaire à nouveau de perdre son temps à rechercher la démarche à suivre sur le net pour une activité déjà réalisée par le passé.</p>
<p>Grâce à ce blog, je pourrai mettre par écrit des astuces qui me sont importantes et qui potentiellement pourront être utiles à d&#8217;autres personnes ou du moins je l&#8217;espère&#8230; De plus, grâce aux commentaires qui pourront être postés sur mes billets, il sera facile de partager ses expériences aux autres internautes.</p>
<p>A bientôt sur ce blog pour de futurs billets !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.itcobalt.ch/2009/05/01/ouverture-du-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
