Parser un fichier xml

Signaler
Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
-
Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
-
Bonsoir,

Je voulais parser mon fichier XML pouyr extraire certaines informations pour les utiliser dans mon programme C.

J'ai trouvé la librairie libxml2 qui est codée en C et qui possède deux méthodes DOM et SAX.

J'ai bien installé libxml2 et j'ai décidé de travailler avec la méthode SAX qui permet de parser des fichiers XML assez grand et n'est pas gourmande en mémoire.

J'ai trouvé des exemples en général et non simples pour un débutant sur le site officiel de libxml2. Ces exemples sont plus pour la méthode DOM. Je ne trouve pas un exemple pour SAX.

- Est ce que il y a quelqu'un qui a rencontré ce type de problème ?

- Pouvez vous me donner un exemple typique pour que j'applique sur mon fichier XML car j'ai besoin des informations qui se trouvent dans le dernier noeud de mon fichier XML ?

Merci.

208 réponses

Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
5
Bonjour,

En réalité, je voudrais lire des informations à partir d'un fichier XML pour les utiliser après dans mon programme C. Ce fichier XML est assez volumineux. Ce fichier a une structure bien définie.
En général voici la structure de ce fichier:
On trouve :
- le type de document
- le nombre d'objets, le nombre d'attributs et le nombre des concepts
- le nom de lattice
- la liste des objets
- le liste des attributs
- la liste des concepts

Je m'intéresse à liste des concepts dans mon programme C.

Voici en général la structure de ce fichier "nom.lat.xml"
<Galicia_Document>
<Lattice numberObj= "5" numberAtt="4" numberCpt= "11">
<Name>lattice(essai)</Name>
<Object>3</Object>
.....
<Object>4</Object>
b
........
a
<Concept>
1
<Extent>
<Object_Ref>3</Object_Ref>
<Object_Ref>2</Object_Ref>
<Object_Ref>1</Object_Ref>
<Object_Ref>5</Object_Ref>
<Object_Ref>4</Object_Ref>
</Extent>




........
.........
.......
11
<Extent>
</Extent>

d
b
c
a


<Concept_Ref>10</Concept_Ref>
<Concept_Ref>8</Concept_Ref>
<Concept_Ref>9</Concept_Ref>
<Concept_Ref>7</Concept_Ref>


</Concept>

Comment je vais positionner sur le dernier identifiant 11
pour extraire toutes les valeurs de balise qui existent entre les deux balises ?


d
b
c
a


Ces valeurs d, b, c et a je vais les utiliser dans mon programme C.
Aussi de même, je veux lire les valeurs 10, 8, 9 et 7 entre les deux balises <Concept_Ref>
</Concept_Ref> qui existent sous les balises


<Concept_Ref>10</Concept_Ref>
<Concept_Ref>8</Concept_Ref>
<Concept_Ref>9</Concept_Ref>
<Concept_Ref>7</Concept_Ref>


Voici mon fichier XML complet nommé "essai.lat.xml":
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172



<Galicia_Document>
<Lattice numberObj  ="5" numberAtt="4" numberCpt="11">
<Name>lattice(essai)</Name>
<Object>3</Object>
<Object>2</Object>
<Object>1</Object>
<Object>5</Object>
<Object>4</Object>
d
b
c
a
<Concept>
 1 
<Extent>
<Object_Ref>3</Object_Ref>
<Object_Ref>2</Object_Ref>
<Object_Ref>1</Object_Ref>
<Object_Ref>5</Object_Ref>
<Object_Ref>4</Object_Ref>
</Extent>




</Concept>
<Concept>
 2 
<Extent>
<Object_Ref>1</Object_Ref>
<Object_Ref>5</Object_Ref>
</Extent>

a


<Concept_Ref>1</Concept_Ref>

</Concept>
<Concept>
 5 
<Extent>
<Object_Ref>2</Object_Ref>
<Object_Ref>5</Object_Ref>
<Object_Ref>4</Object_Ref>
</Extent>

b


<Concept_Ref>1</Concept_Ref>

</Concept>
<Concept>
 4 
<Extent>
<Object_Ref>3</Object_Ref>
<Object_Ref>1</Object_Ref>
<Object_Ref>4</Object_Ref>
</Extent>

c


<Concept_Ref>1</Concept_Ref>

</Concept>
<Concept>
 3 
<Extent>
<Object_Ref>3</Object_Ref>
<Object_Ref>2</Object_Ref>
<Object_Ref>5</Object_Ref>
</Extent>

d


<Concept_Ref>1</Concept_Ref>

</Concept>
<Concept>
 8 
<Extent>
<Object_Ref>1</Object_Ref>
</Extent>

c
a


<Concept_Ref>2</Concept_Ref>
<Concept_Ref>4</Concept_Ref>

</Concept>
<Concept>
 9 
<Extent>
<Object_Ref>4</Object_Ref>
</Extent>

b
c


<Concept_Ref>5</Concept_Ref>
<Concept_Ref>4</Concept_Ref>

</Concept>
<Concept>
 6 
<Extent>
<Object_Ref>2</Object_Ref>
<Object_Ref>5</Object_Ref>
</Extent>

d
b


<Concept_Ref>5</Concept_Ref>
<Concept_Ref>3</Concept_Ref>

</Concept>
<Concept>
 7 
<Extent>
<Object_Ref>3</Object_Ref>
</Extent>

d
c


<Concept_Ref>4</Concept_Ref>
<Concept_Ref>3</Concept_Ref>

</Concept>
<Concept>
 10 
<Extent>
<Object_Ref>5</Object_Ref>
</Extent>

d
b
a


<Concept_Ref>2</Concept_Ref>
<Concept_Ref>6</Concept_Ref>

</Concept>
<Concept>
 11 
<Extent>
</Extent>

d
b
c
a


<Concept_Ref>10</Concept_Ref>
<Concept_Ref>8</Concept_Ref>
<Concept_Ref>9</Concept_Ref>
<Concept_Ref>7</Concept_Ref>

</Concept>
</Lattice>
</Galicia_Document>


Vue que la première fois que je parse un fichier XML alors je ne
comprends pas le principe de le faire. par exemple dans la
manipulation de fichier texte. Il faut:
- tester l'existence du fichier
- ouvrir le fichier
- lire le fichier
- traitement
- fermeture.

Par analogie comment je vais lire les informations existant dans la
dernière balise de mon fichier XML ?

Je m'intéresse au cette partie (dernière balise "concep") du mon
fichier :
<Concept>
 11 
<Extent>
</Extent>

d
b
c
a


<Concept_Ref>10</Concept_Ref>
<Concept_Ref>8</Concept_Ref>
<Concept_Ref>9</Concept_Ref>
<Concept_Ref>7</Concept_Ref>

</Concept>


Je voudrais stocker les valeurs qui existent entre les sous balises
pour les utiliser dans mon programme C.

- <Extent> </Extent>
-
-

Comment je vais extraire ces valeurs ?

C'est urgent. Aidez-moi je suis bloqué.

Merci.
Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
5
Voici mon fichier XML complet nommé "essai.lat.xml":

<Galicia_Document>

<Lattice numberObj="5" numberAtt="4" numberCpt="11">

<Name>lattice(essai)</Name>

<Object>3</Object>

<Object>2</Object>

<Object>1</Object>

<Object>5</Object>

<Object>4</Object>

d

b

c

a

<Concept>

 1 

<Extent>

<Object_Ref>3</Object_Ref>

<Object_Ref>2</Object_Ref>

<Object_Ref>1</Object_Ref>

<Object_Ref>5</Object_Ref>

<Object_Ref>4</Object_Ref>

</Extent>









</Concept>

<Concept>

 2 

<Extent>

<Object_Ref>1</Object_Ref>

<Object_Ref>5</Object_Ref>

</Extent>



a





<Concept_Ref>1</Concept_Ref>



</Concept>

<Concept>

 5 

<Extent>

<Object_Ref>2</Object_Ref>

<Object_Ref>5</Object_Ref>

<Object_Ref>4</Object_Ref>

</Extent>



b





<Concept_Ref>1</Concept_Ref>



</Concept>

<Concept>

 4 

<Extent>

<Object_Ref>3</Object_Ref>

<Object_Ref>1</Object_Ref>

<Object_Ref>4</Object_Ref>

</Extent>



c





<Concept_Ref>1</Concept_Ref>



</Concept>

<Concept>

 3 

<Extent>

<Object_Ref>3</Object_Ref>

<Object_Ref>2</Object_Ref>

<Object_Ref>5</Object_Ref>

</Extent>



d





<Concept_Ref>1</Concept_Ref>



</Concept>

<Concept>

 8 

<Extent>

<Object_Ref>1</Object_Ref>

</Extent>



c

a





<Concept_Ref>2</Concept_Ref>

<Concept_Ref>4</Concept_Ref>



</Concept>

<Concept>

 9 

<Extent>

<Object_Ref>4</Object_Ref>

</Extent>



b

c





<Concept_Ref>5</Concept_Ref>

<Concept_Ref>4</Concept_Ref>



</Concept>

<Concept>

 6 

<Extent>

<Object_Ref>2</Object_Ref>

<Object_Ref>5</Object_Ref>

</Extent>



d

b





<Concept_Ref>5</Concept_Ref>

<Concept_Ref>3</Concept_Ref>



</Concept>

<Concept>

 7 

<Extent>

<Object_Ref>3</Object_Ref>

</Extent>



d

c





<Concept_Ref>4</Concept_Ref>

<Concept_Ref>3</Concept_Ref>



</Concept>

<Concept>

 10 

<Extent>

<Object_Ref>5</Object_Ref>

</Extent>



d

b

a





<Concept_Ref>2</Concept_Ref>

<Concept_Ref>6</Concept_Ref>



</Concept>

<Concept>

 11 

<Extent>

</Extent>



d

b

c

a





<Concept_Ref>10</Concept_Ref>

<Concept_Ref>8</Concept_Ref>

<Concept_Ref>9</Concept_Ref>

<Concept_Ref>7</Concept_Ref>



</Concept>

</Lattice>

</Galicia_Document>

Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
5
Bonjour,

- C'est quoi la différence entre l'utilisation du méthode DOM, SAX et XPath ?
- Quelle est la méthode la plus adaptée pour la manipulation pour traiter des fichiers XML assez volumineux et le moins consommation en mémoire ?

A mon avis C'est SAX.

Pouvez me donner un exemple de méthode SAX qui me répond à mon besoin ?

Merci.
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
fais toi plaisir

http://developerlife.com/tutorials/?p=28

Renfield - Admin CodeS-SourceS - MVP Visual Basic
Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
5
Bonjour,

Ce lien concerne DOM et SAX pour le Java.
Moi, je cherche la méthode SAX coté la librairie Libxml2.

Merci.
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
Ca ne change rien... SAX c'est SAX...

ca dit que SAX va lire ton flux XML et appeler des fonctions pour tel ou tel type d'info récupérée

DOM me semble donc bien plus adapté a ton cas...
il stocke sous forme d'arborescence le floux XML en mémoire et te permet de récupérer efficacement tes données, via une bête requete.

Renfield - Admin CodeS-SourceS - MVP Visual Basic
Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
5
Bonjour,

La méthode SAX est mieux que DOM concernant la manipulation des fichiers XML assez volumineux de plus elle consomme le moins de mémoire.

De plus votre exemple est en java et non pas en C.
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
peu importe le langage, la libxml2 reste la même...

google est ton ami...
si depuis ce matin tu attend (quoi ?) de taper :

libxml2 sax sample

dans google, j'avoue ignorer pourquoi...

ca donne de bons résultats rapidement:

http://www.jamesh.id.au/articles/libxml-sax/libxml-sax.html


Renfield - Admin CodeS-SourceS - MVP Visual Basic
Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
5
Bonjour,

J'ai lu beaucoup des fois la documentation de libxml2. Mais, je n'arrive pas à trouver une solution à mon problème car c'est la première fois que je fais la manipulation de fichier XML dans un programme C en utilisant la méthode SAX de la librairie Iibxml2. De plus, le reste du mon travail se base sur le résultat trouvé dans la solution de ce problème.
Je veux utiliser la solution proposée par vous comme une fonction pour l'appeler dans mon programme.
Mon travail consiste à faire deux choses (deux fonctions) :

- la première fonction permet d'extraire les informations (qui sont des chaines de caractères) qui existent entre la balise et <\intent> concernant le dernier identificateur <\ID> du dernière balise <concept> <\concept>

cette fonction nous donne comme un résultat un tableau ou un fichier contenant :
"d b c a"

Dans notre cas ici, on aura une seule ligne du fichier ou bien une seule case du tableau contenant "d b c a"

- La deuxième fonction permet d'extraire les informations (chaines de caractères) qui existent entre la balise et <\intent> de tous les identificateurs <\ID> sauf le dernier identificateur <\ID>

et si la balise <\intent> du premier identificateur <\ID> n'est pas vide alors nous mettons l'information entre <\intent> dans le résultat

Sinon si la balise <\intent> du premier identificateur <\ID> est vide comme dans notre cas alors nous ne mettons pas l'information entre <\intent> dans le résultat.
cette fonction nous donne comme un résultat un tableau ou un fichier contenant les chaines de caractères recherchées.

Dans notre cas ici, on aura des lignes du fichier ou bien des cases du tableau contenant:
"a"
"b"
"c"
"d"
"a c"
"b c"
"b d"
"c d"
"a b d"

Voici mon fichier XML complet nommé "essai.xml":
<Galicia_Document>
<Lattice numberObj= "5" numberAtt="4" numberCpt="11">

<Name>lattice(essai)</Name>
<Object>3</Object>
<Object>2</Object>

<Object>1</Object>

<Object>5</Object>
<Object>4</Object>

d
b

c

a
<Concept>
  1  

<Extent>

<Object_Ref>3</Object_Ref>
<Object_Ref>2</Object_Ref>
<Object_Ref>1</Object_Ref>


<Object_Ref>5</Object_Ref>
<Object_Ref>4</Object_Ref>
</Extent>






</Concept>

<Concept>
 2 
<Extent>

<Object_Ref>1</Object_Ref>

<Object_Ref>5</Object_Ref>
</Extent>

a




<Concept_Ref>1</Concept_Ref>


</Concept>
<Concept>

 5 
<Extent>
<Object_Ref>2</Object_Ref>

<Object_Ref>5</Object_Ref>

<Object_Ref>4</Object_Ref>
</Extent>


b




<Concept_Ref>1</Concept_Ref>

</Concept>
<Concept>

 4 

<Extent>
<Object_Ref>3</Object_Ref>
<Object_Ref>1</Object_Ref>

<Object_Ref>4</Object_Ref>

</Extent>

c



<Concept_Ref>1</Concept_Ref>



</Concept>
<Concept>
 3 
<Extent>
<Object_Ref>3</Object_Ref>


<Object_Ref>2</Object_Ref>
<Object_Ref>5</Object_Ref>
</Extent>


d




<Concept_Ref>1</Concept_Ref>

</Concept>
<Concept>


 8 
<Extent>
<Object_Ref>1</Object_Ref>
</Extent>



c
a



<Concept_Ref>2</Concept_Ref>

<Concept_Ref>4</Concept_Ref>


</Concept>
<Concept>
 9 

<Extent>

<Object_Ref>4</Object_Ref>
</Extent>

b


c


<Concept_Ref>5</Concept_Ref>

<Concept_Ref>4</Concept_Ref>


</Concept>
<Concept>

 6 
<Extent>
<Object_Ref>2</Object_Ref>

<Object_Ref>5</Object_Ref>

</Extent>

d
b




<Concept_Ref>5</Concept_Ref>
<Concept_Ref>3</Concept_Ref>



</Concept>
<Concept>
 7 
<Extent>

<Object_Ref>3</Object_Ref>

</Extent>

d

c



<Concept_Ref>4</Concept_Ref>

<Concept_Ref>3</Concept_Ref>

</Concept>

<Concept>

 11 
<Extent>
<Object_Ref>5</Object_Ref>
</Extent>



d
b

a



<Concept_Ref>2</Concept_Ref>

<Concept_Ref>6</Concept_Ref>


</Concept>
<Concept>

 10 
<Extent>
</Extent>

d


b
c
a




<Concept_Ref>10</Concept_Ref>
<Concept_Ref>8</Concept_Ref>

<Concept_Ref>9</Concept_Ref>

<Concept_Ref>7</Concept_Ref>


</Concept>
</Lattice>
</Galicia_Document>



Voici mon code en se basant sur le lien
http://julp.developpez.com/c/libxml2/?page =sax
mais ne me répond pas à mon besoin :

#include <stdlib.h>
#include <string.h>
#include <libxml/parser.h>

 /* -------------------------------------------- */

#define MAX 10
#define END -1

typedef struct {

    int Object_Ref[MAX];
    int Attribute_Ref[MAX];
    int Concept_Ref[MAX];

} _Concept;

typedef struct {

    int id;
    _Concept *concept;

} Concept;

/* -------------------------------------------- */

enum ElmtType { ID, OBJ_REF, ATTR_REF, CONCPT_REF, AUTRE };

enum ElmtType cur_elmt = AUTRE;
_Concept *p_concept;

void debut_element(void *user_data, const xmlChar *name, const xmlChar **attrs)
{
    if (!xmlStrcmp(name, "ID"))
        cur_elmt = ID;
    else if (!xmlStrcmp(name, "Attribute_Ref"))
        cur_elmt = ATTR_REF;
    else if (!xmlStrcmp(name, "Concept_Ref"))
        cur_elmt = CONCPT_REF;
    else if (!xmlStrcmp(name, "Object_Ref"))
        cur_elmt = OBJ_REF;
    else
        cur_elmt = AUTRE;
}

void caracteres(void *user_data, const xmlChar *ch, int len)
{
    Concept *c = user_data;

    if(cur_elmt == ID)
    {
        int id = strtod(ch,NULL);
        int i=0;

        /* est-ce que cet ID nous interesse ? */
        while(c[i].id != id && c[i].id != END)
            i++;
        if(c[i].id == id)
        {
            /* si oui on alloue une nouvelle structure _Concept pour enregistrer
            les infos qui viendront ensuite */
            c[i].concept = malloc(sizeof (_Concept));
            memset(c[i].concept,END,sizeof(_Concept));
            p_concept = c[i].concept;
        }
        else
            p_concept = NULL;
    }
    else if(cur_elmt == OBJ_REF)
    {
        if(p_concept != NULL)
        {
            /* cherche la premiere case de libre */
            int *p = p_concept->Object_Ref;
            while(*p != END)
                p++;

            *p = strtod(ch,NULL);
        }
    }
    else if(cur_elmt == ATTR_REF)
    {
        if(p_concept != NULL)
        {
            int *p = p_concept->Attribute_Ref;
            while(*p != END)
                p++;

            *p = ch[0];
        }
    }
    else if(cur_elmt == CONCPT_REF)
    {
        if(p_concept != NULL)
        {
            int *p = p_concept->Concept_Ref;
            while(*p != END)
                p++;

            *p = strtod(ch,NULL);
        }
    }
}

void fin_element(void *user_data, const xmlChar *name)
{
    cur_elmt = AUTRE;
}

Concept* Concept_Load(const char *path, Concept *c)
{
    xmlSAXHandler sh = { 0 };

    sh.startElement = debut_element;
    sh.characters = caracteres;
    sh.endElement = fin_element;

    if (xmlSAXUserParseFile(&sh, c, path) != 0)
        return NULL;

    return c;
}

/* -------------------------------------------- */

int main(void)
{
    int i;

    Concept c[] = { {11,NULL}, {6,NULL}, {78,NULL}, {END,NULL} };

    Concept_Load("f.xml",c);

    for (i=0; c[i].id != END; i++)
    {
        printf("-- Concept --\n");
        printf("ID = %d\n",c[i].id);

        if (c[i].concept != NULL)
        {
            int j=0;
            printf("Object Ref : ");
            while (c[i].concept->Object_Ref[j] != END)
                printf("%d ",c[i].concept->Object_Ref[j++]);
            printf("\n");

            j=0;
            printf("Attribute Ref : ");
            while (c[i].concept->Attribute_Ref[j] != END)
                printf("%c ",c[i].concept->Attribute_Ref[j++]);
            printf("\n");

            j=0;
            printf("Concept Ref : ");
            while (c[i].concept->Concept_Ref[j] != END)
                printf("%d ",c[i].concept->Concept_Ref[j++]);
            printf("\n\n");
        }
        else
            printf("pas trouve.\n");
    }

    return 0;
}



Je serais très reconnaissant si vous m'aidez car j'ai besoin énormément de la solution à mon problème.

Merci.
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
comme je te le disais, comme la doc te le dit surement et comme le code nous le montre, SAX appelle une fonction pour chaque ouverture de noeud, une fonction pour chaque fermeture et une autre pour le contenu.

du coup, c'est a toi de faire le boulot, adapter les appels a ta logique, garder une trace de l'arborescence, si tu en as besoin.

pour récupérer les infos du dernierr intent...
tu attends l'ouverture

<Lattice numberObj="5" numberAtt="4" numberCpt="11">

tu mémorise le numberCpt
et tu compte les que SAX te soumet.

quand arrive le 11eme, tu en extraies les infos.


l'autre fonction n'est pas plus complexe.


ton code actuel me donne l'impression d'etre un brin complexe, inutilement.


Renfield - Admin CodeS-SourceS - MVP Visual Basic
Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
5
Bonjour,

pour récupérer les infos du dernierr intent...
tu attends l'ouverture

<Lattice numberObj="5" numberAtt="4" numberCpt="11">

tu mémorise le numberCpt
et tu compte les que SAX te soumet.

quand arrive le 11eme, tu en extraies les infos.



Oui.c'est çà l'idée. Mais, je n'arrive à coder ces étapes:
- attendre l'ouverture
- mémorise le numberCpt
- compte les
- extraire les infos
car je ne sais pas comment je vais tester,...
car c'est la première fois que je parse un fichier xml.



ton code actuel me donne l'impression d'etre un brin complexe, inutilement.


Quelles sont les parties de code qui sont inutiles ?

Pouvez vous proposez un exemple de solution ?

J'ai besoin de votre aide.

Merci.
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <libxml/parser.h>
#pragma comment(lib,"libxml2.lib")

int _numberCpt = 0;
bool _mustMem = false;

void startElement(void *user_data, 	const xmlChar *name, const xmlChar **attrs){
if (!xmlStrcmp(name, (xmlChar*)"Lattice") && attrs) {
        for (int i = 0; attrs[i]; i+=2){
            if (!xmlStrcmp(attrs[i], (xmlChar*)"numberCpt")) {
_numberCpt = strtol((const char*)attrs[i+1],NULL,0);
break;
            }
        }
}
else if (!xmlStrcmp(name, (xmlChar*)"Concept") && _numberCpt)
_numberCpt--;
else if (!xmlStrcmp(name, (xmlChar*)"Attribute_Ref") && !_numberCpt)
_mustMem = true;
}

void characters(	void * 	user_data, 	const xmlChar *ch, 	int len) {
if (_mustMem) 
{
char* s = (char *)malloc(sizeof(char)*len+1);
*(s+len) = 0;
strncpy(s,(const char*)ch,len);
printf("%s\n", s);
_mustMem = false;
}
}

int _tmain(int argc, _TCHAR* argv[])
{
    xmlSAXHandler sh = { 0 };
sh.startElement = startElement;
    sh.characters = characters;

    if (xmlSAXUserParseFile(&sh, NULL, "D:\\Documents and Settings\\THOM31R\\Bureau\\libxml2-2.7.3.win32\\ParseSample\\ParseSample\\Input.xml"))
        return NULL;

system ("pause");
return 0;
}


Renfield - Admin CodeS-SourceS - MVP Visual Basic
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
pour l'autre fonction, j'ai pas forcément bien compris..

partant de mon code, tu peux tester
_numberCpt pour savoir si tu es sur les dernier noeud ou pas.


nb: c'est pas <\itent>


Renfield - Admin CodeS-SourceS - MVP Visual Basic
Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
5
Bonjour,
lorsque je compile votre code dans mon projet C j'obtiens l'erreur suivant:


1>------ Début de la génération : Projet : parseure, Configuration : Debug Win32 ------
1>Compilation en cours...
1>main.c
1>c:\parseure\parseure\main.c(1) : fatal error C1083: Impossible d'ouvrir le fichier include : 'stdafx.h' : No such file or directory
1>Le journal de génération a été enregistré à l'emplacement "file://c:\parseure\parseure\Debug\BuildLog.htm"
1>parseure - 1 erreur(s), 0 avertissement(s)
======== Génération : 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========
1)
A quoi sert? :
- stdafx.h
- l'instruction :
"D:\\Documents and Settings\\THOM31R\\Bureau\\libxml2-2.7.3.win32\\ParseSample\\ParseSample\\Input.xml"

2) Est ce que votre code permet de lire mon fichier XML "essai.xml" car je ne vois pas la lecture de ce fichier dans votre code ?

3) Que ce que il donne votre code comme résultat ?

4) Avez obtenu le résultat que je suis entrain de rechercher ?

Je serais très contente si vous me trouvez une solution car je suis bloquée.

Merci.
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
à quoi sert :
"D:\\Documents and Settings\\THOM31R\\Bureau\\libxml2-2.7.3.win32\\ParseSample\\ParseSample\\Input.xml"

euh...
ben c'est le chemin vers mon fichier XML....

stdafx...
oublie, c'est lié à mon environnement de travail (Visual Studio)

que donne mon code ?
d
b
c
a
Appuyez sur une touche pour continuer...





Renfield - Admin CodeS-SourceS - MVP Visual Basic
Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
5
Bonjour,

Mon projet C est avec visual studio 2008 sous windows.

J'ai enlevé "stdafx" et j'ai changé le chemin vers mon fichier xml.

Voici le code :


#include <stdlib.h>

#include <string.h>

#include <libxml/parser.h>

#pragma comment(lib,"libxml2.lib")



int _numberCpt = 0;

bool _mustMem = false;



void startElement(void *user_data, 	const xmlChar *name, const xmlChar **attrs){

if (!xmlStrcmp(name, (xmlChar*)"Lattice") && attrs) {

        for (int i = 0; attrs[i]; i+=2){

            if (!xmlStrcmp(attrs[i], (xmlChar*)"numberCpt")) {

_numberCpt = strtol((const char*)attrs[i+1],NULL,0);

break;

            }

        }

}

else if (!xmlStrcmp(name, (xmlChar*)"Concept") && _numberCpt)

_numberCpt--;

else if (!xmlStrcmp(name, (xmlChar*)"Attribute_Ref") && !_numberCpt)

_mustMem = true;

}



void characters(	void * 	user_data, 	const xmlChar *ch, 	int len) {

if (_mustMem) 

{

char* s = (char *)malloc(sizeof(char)*len+1);

*(s+len) = 0;

strncpy(s,(const char*)ch,len);

printf("%s\n", s);

_mustMem = false;

}

}



int _tmain(int argc, _TCHAR* argv[])

{

    xmlSAXHandler sh = { 0 };

sh.startElement = startElement;

    sh.characters = characters;



    if (xmlSAXUserParseFile(&sh, NULL, "C:\\parseure\\parseure\\essai.xml"))

        return NULL;



system ("pause");

return 0;

}



Après la compilation, il y a 25 erreurs :

1>------ Début de la génération : Projet : parseure, Configuration : Debug Win32 ------
1>Compilation en cours...
1>main.c
1>c:\parseure\parseure\main.c(14) : error C2061: erreur de syntaxe : identificateur '_mustMem'
1>c:\parseure\parseure\main.c(14) : error C2059: erreur de syntaxe : ';'
1>c:\parseure\parseure\main.c(14) : error C2513: '/*global*/ ' : aucune variable déclarée avant '='
1>c:\parseure\parseure\main.c(14) : error C2065: 'false' : identificateur non déclaré
1>c:\parseure\parseure\main.c(22) : error C2143: erreur de syntaxe : absence de ';' avant 'type'
1>c:\parseure\parseure\main.c(22) : error C2143: erreur de syntaxe : absence de ';' avant 'type'
1>c:\parseure\parseure\main.c(22) : error C2143: erreur de syntaxe : absence de ')' avant 'type'
1>c:\parseure\parseure\main.c(22) : error C2143: erreur de syntaxe : absence de ';' avant 'type'
1>c:\parseure\parseure\main.c(22) : error C2065: 'i' : identificateur non déclaré
1>c:\parseure\parseure\main.c(22) : error C2065: 'i' : identificateur non déclaré
1>c:\parseure\parseure\main.c(22) : error C2059: erreur de syntaxe : ')'
1>c:\parseure\parseure\main.c(22) : error C2143: erreur de syntaxe : absence de ';' avant '{'
1>c:\parseure\parseure\main.c(24) : error C2065: 'i' : identificateur non déclaré
1>c:\parseure\parseure\main.c(26) : error C2065: 'i' : identificateur non déclaré
1>c:\parseure\parseure\main.c(28) : error C2043: instruction break non conforme
1>c:\parseure\parseure\main.c(42) : error C2065: '_mustMem' : identificateur non déclaré
1>c:\parseure\parseure\main.c(42) : error C2065: 'true' : identificateur non déclaré
1>c:\parseure\parseure\main.c(50) : error C2065: '_mustMem' : identificateur non déclaré
1>c:\parseure\parseure\main.c(62) : error C2065: '_mustMem' : identificateur non déclaré
1>c:\parseure\parseure\main.c(62) : error C2065: 'false' : identificateur non déclaré
1>c:\parseure\parseure\main.c(70) : error C2143: erreur de syntaxe : absence de ')' avant '*'
1>c:\parseure\parseure\main.c(70) : error C2081: '_TCHAR' : nom non conforme dans la liste de paramètres formels
1>c:\parseure\parseure\main.c(70) : error C2143: erreur de syntaxe : absence de '{' avant '*'
1>c:\parseure\parseure\main.c(70) : error C2059: erreur de syntaxe : ')'
1>c:\parseure\parseure\main.c(72) : error C2054: '(' attendu après 'argv'
1>Le journal de génération a été enregistré à l'emplacement "file://c:\parseure\parseure\Debug\BuildLog.htm"
1>parseure - 25 erreur(s), 0 avertissement(s)
======== Génération : 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========

Comment corriger ces erreurs ?

Merci.
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
normal : tu compiles en C

je t'ai filé du cpp

Renfield - Admin CodeS-SourceS - MVP Visual Basic
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
pas sorcier de changer bool en int
de virer la déclaration int i dans
for (int i

pour la déclarer avant...

ce qui donne, en c :
// ParseSample.cpp : définit le point d'entrée pour l'application console.
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <libxml/parser.h>
#pragma comment(lib,"libxml2.lib")

int _numberCpt = 0;
int _mustMem = 0;

void startElement(void *user_data, 	const xmlChar *name, const xmlChar **attrs){
int i;
if (!xmlStrcmp(name, (xmlChar*)"Lattice") && attrs) {
        for (i = 0; attrs[i]; i+=2){
            if (!xmlStrcmp(attrs[i], (xmlChar*)"numberCpt")) {
_numberCpt = strtol((const char*)attrs[i+1],NULL,0);
break;
            }
        }
}
else if (!xmlStrcmp(name, (xmlChar*)"Concept") && _numberCpt)
_numberCpt--;
else if (!xmlStrcmp(name, (xmlChar*)"Attribute_Ref") && !_numberCpt)
_mustMem = 1;
}

void characters(void* user_data, const xmlChar *ch, int len) {
if (_mustMem) 
{
char* s = (char *)malloc(sizeof(char)*len+1);
*(s+len) = 0;
strncpy(s,(const char*)ch,len);
printf("%s\n", s);
_mustMem = 0;
}
}

int _tmain(int argc, _TCHAR* argv[])
{
    xmlSAXHandler sh = { 0 };
sh.startElement = startElement;
    sh.characters = characters;

    if (xmlSAXUserParseFile(&sh, NULL, "D:\\Documents and Settings\\THOM31R\\Bureau\\libxml2-2.7.3.win32\\ParseSample\\ParseSample\\Input.xml"))
        return NULL;

system ("pause");
return 0;
}





Renfield - Admin CodeS-SourceS - MVP Visual Basic
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
et zou, ça fonctionne même compilé en c...

et si ton compilo t'embete avec main...
pas grave, mets simplement :

int main()
{
    ....
}



Renfield - Admin CodeS-SourceS - MVP Visual Basic
Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
5
Bonjour,

Voici le nouveau code C avec Visual Studio 2008 :
#include <stdlib.h>
#include <string.h>
#include <libxml/parser.h>
#pragma comment(lib,"libxml2.lib")

int _numberCpt = 0;

bool _mustMem = false;

void startElement(void *user_data, 	const xmlChar *name, const xmlChar **attrs){

int i;
if (!xmlStrcmp(name, (xmlChar*)"Lattice") && attrs) {

        for ( i = 0; attrs[i]; i+=2){

            if (!xmlStrcmp(attrs[i], (xmlChar*)"numberCpt")) {

_numberCpt = strtol((const char*)attrs[i+1],NULL,0);

break;

            }

        }

}

else if (!xmlStrcmp(name, (xmlChar*)"Concept") && _numberCpt)

_numberCpt--;

else if (!xmlStrcmp(name, (xmlChar*)"Attribute_Ref") && !_numberCpt)

_mustMem = true;

}

void characters(	void * 	user_data, 	const xmlChar *ch, 	int len) {

if (_mustMem) 

{

char* s = (char *)malloc(sizeof(char)*len+1);

*(s+len) = 0;

strncpy(s,(const char*)ch,len);

printf("%s\n", s);

_mustMem = false;
}
}

int main()

{

    xmlSAXHandler sh = { 0 };

sh.startElement = startElement;

    sh.characters = characters;

    if (xmlSAXUserParseFile(&sh, NULL, "C:\\parseure\\parseure\\essai.xml"))

        return NULL;



system ("pause");

return 0;

}


voici erreurs ce code que j'obtiens après la compilation

1>------ Début de la génération : Projet : parseure, Configuration : Debug Win32 ------
1>Compilation en cours...
1>main.c
1>c:\parseure\parseure\main.c(13) : error C2061: erreur de syntaxe : identificateur '_mustMem'
1>c:\parseure\parseure\main.c(13) : error C2059: erreur de syntaxe : ';'
1>c:\parseure\parseure\main.c(13) : error C2513: '/*global*/ ' : aucune variable déclarée avant '='
1>c:\parseure\parseure\main.c(13) : error C2065: 'false' : identificateur non déclaré
1>c:\parseure\parseure\main.c(42) : error C2065: '_mustMem' : identificateur non déclaré
1>c:\parseure\parseure\main.c(42) : error C2065: 'true' : identificateur non déclaré
1>c:\parseure\parseure\main.c(50) : error C2065: '_mustMem' : identificateur non déclaré
1>c:\parseure\parseure\main.c(62) : error C2065: '_mustMem' : identificateur non déclaré
1>c:\parseure\parseure\main.c(62) : error C2065: 'false' : identificateur non déclaré
1>Le journal de génération a été enregistré à l'emplacement "file://c:\parseure\parseure\Debug\BuildLog.htm"
1>parseure - 9 erreur(s), 0 avertissement(s)
======== Génération : 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========



Ces erreurs sont liés à la déclaration et l'utilisation de la variable _mustMem

C'est quoi le rôle de cette variable ?
et comment la définie correctement dans ce code ?

Merci.