IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèques C++ Discussion :

LibXML2:Paser un fichier XML en C++ (problèmes spécifiques)


Sujet :

Bibliothèques C++

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mars 2010
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Mars 2010
    Messages : 62
    Points : 33
    Points
    33
    Par défaut LibXML2:Paser un fichier XML en C++ (problèmes spécifiques)
    Bonjour a tous,

    Voila j'explique: j'ai installé la librairie libxml2. Que j'utilise en C++.
    Et je veux parser un fichier XML et récuperer des informations.
    J'ai créé un fichier XML.

    Code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <ParamEcu>
    	<ECUTR2Info>
    		<EcuName>TR2</EcuName>
    		<AdresseEmmission>0xCDA04F9</AdresseEmmission>
    		<AdresseReception>0xCDAF904</AdresseReception>
    		<SeedValue>2F89</SeedValue>
    	</ECUTR2Info>
    	<ECUTR3Info>
    		<EcuName>TR3</EcuName>
    		<AdresseEmmission>0xCDA09F9</AdresseEmmission>
    		<AdresseReception> 0xCDAF909</AdresseReception>
    		<SeedValue>2F89</SeedValue>
    	</ECUTR3Info>
    	<ECUSFAInfo>
    		<EcuName>SFA</EcuName>
    		<AdresseEmmission>0xCDA15F9</AdresseEmmission>
    		<AdresseReception>0xCDAF915</AdresseReception>
    		<SeedValue>2DAB</SeedValue>
    	</ECUSFAInfo>
    </ParamEcu>
    Enfaite ce que je veux c'est récuperer a chaque fois les information EcuName, AdresseEmmission et AdresseReception en format unsigned long. Car la fonction qui utilisera ces paramètres es veux en unsigned long. Et ça je ne peux le changer.

    J'ai fait ceci dans mon code c++:

    Code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    unsigned long CalculateurXML::getAdresseReception()
    {
       	// Initialisation de l'environnement XPath
    	xmlXPathInit();
    	xmlDocPtr doc;
    	int j=0;
    	xmlChar *pxpathEcuAdresseReception;
    	//Chemin des informations dans le XML TR2
    	if (ptrCRecuperation_CalculateursDlg->calculo == TR2)
    	{
    		pxpathEcuAdresseReception = (xmlChar*) "/ParamEcu/ECUTR2Info/AdresseReception/text()";
    	}
    	//Chemin des informations dans le XML TR3
    	else if (ptrCRecuperation_CalculateursDlg->calculo == TR3)
    	{
    		pxpathEcuAdresseReception = (xmlChar*) "/ParamEcu/ECUTR3Info/AdresseReception/text()";
    	}
    	//Chemin des informations dans le XML SFA
    	else if (ptrCRecuperation_CalculateursDlg->calculo == SFA)
    	{
    		pxpathEcuAdresseReception = (xmlChar*) "/ParamEcu/ECUSFAInfo/AdresseReception/text()";
    	}
    	xmlXPathObjectPtr xpathRes; 
    	int i;
     
    	// Ouverture du fichier XML
        doc = xmlParseFile("ECU.xml");
        if (doc == NULL) 
    	{
            fprintf(stderr, "Document XML invalide\n");
            //return EXIT_FAILURE;
        }
     
    	// Création du contexte
    	xmlXPathContextPtr ctxt = xmlXPathNewContext(doc); // doc est un xmlDocPtr 
    	if (ctxt == NULL) 
    	{
    		fprintf(stderr, "Erreur lors de la création du contexte XPath\n");
    		xmlFreeDoc(doc); 
    		exit(-1);
    	}
     
     
    		// Evaluation de l'expression XPath
    		xpathRes = xmlXPathEvalExpression(pxpathEcuAdresseReception, ctxt);
    		if (xpathRes == NULL) 
    		{
    			fprintf(stderr, "Erreur sur l'expression XPath\n");
    			exit(-1);
    		}
     
    		// Manipulation du résultat
    		if (xpathRes->type == XPATH_NODESET) 
    		{
    			for (i = 0; i < xpathRes->nodesetval->nodeNr; i++) 
    			{
    				//n noeud dans lequel on est
    				xmlNodePtr n = xpathRes->nodesetval->nodeTab[i];
    				if (n->type == XML_TEXT_NODE || n->type == XML_CDATA_SECTION_NODE) 
    				{
    					AdresseReception=(unsigned long)n->content;
    				}
    			}
    		}
     
    	// Libération de la mémoire
    	xmlXPathFreeObject(xpathRes);
    	xmlXPathFreeContext(ctxt);
    	xmlFreeDoc(doc);
    	return AdresseReception;
    }
    A cette ligne ci:

    Code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AdresseReception=(unsigned long)n->content;
    Je cast en unsigned long pour que ça se raccorde avec ma fonction, le problème c'est que ça change ma valeur
    Dans ma fonction j'ai besoin exactement de:

    Code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fonction(0xCDA09F9); //(par exemple)
    Le paramètre est un unsigned long

    Et ici je fait:
    Code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CalculateurXML xpath;
    fonction(Xpath.getAdresseEmmission());.
    Et ça ne fonctionne pas a cause du cast qui me modifi ma valeure.

    Je ne sais pas si vous avez compris, si je susi assezclair en toutcsa je ne sais pas si l'erreur vient de mon fichier xml ou du C++...

    Merci en tout cas de m'avoir lu.

  2. #2
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Dis-moi, quel est le type de « xmlNodePtr->content » ?
    Hum ?
    Voyons, il faut que ce champ puisse contenir n'importe quel type de données lues depuis le document XML.
    Une chaîne de caractères ?
    Bien vu !

    Plus précisément, « xmlChar * ».
    Du coup, c'est sûr que quand tu essaies de transtyper en entier...
    Il faut utiliser une fonction qui transforme une chaîne de caractères en nombre.
    Je ne sais pas s'il en existe dans la libxml, par contre le standard t'offre le moyen de le faire simplement.
    http://c.developpez.com/faq/?page=st...RINGS_numtostr
    http://cpp.developpez.com/faq/cpp/?p...RINGS_strtonum

  3. #3
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Salut,

    Ne pas oublier le std::hex pour lire des nombres hexadécimaux.

    MAT.

  4. #4
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Oups, oui, en effet.
    J'y ai pensé en lisant le message, mais j'ai complètement oublié en écrivant le mien…

  5. #5
    Nouveau membre du Club
    Inscrit en
    Mars 2010
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Mars 2010
    Messages : 62
    Points : 33
    Points
    33
    Par défaut
    Merci pour vos réponse.
    Je suis vraiment désolé mais je ne comprend pas.
    J'ai donc un XmlChar* que je dois convertir en int,le problème étant qu'avec le
    XmlChar*=CDA04F9
    Je veux me trouver avec un unsgned long: 0xCDA04F9
    Or je n'arrive pas très bien a comprendre avec les fonctions.

    Croyez moi je n'y met pas de la mauvaise volonté.

  6. #6
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Les conversions « char* -> xmlChar* » et « xmlChar* -> char* » peuvent être faites grâce à un simple cast, à condition qu'il n'y ait que des caractères ASCII (les chiffres et les lettres non accentuées (a-z) en font partie).
    La conversion « char* -> std::string » est implicite.

    Pour le reste, les réponses se trouvent dans les liens que Mat007 et moi t'avons donnés.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <sstream>
     
     
    (...)
     
    xmlNodePtr n;
    (...)
    /* À ce point, on suppose que n est un nœud dont la valeur est un nombre hexadécimal.
     * Donc n->value = `un nombre sous forme hexadécimale`. */
    std::istringstream iss(static_cast<char*>(n->value));
    unsigned long AdresseReception;
    iss >> std::hex >> AdresseReception;
    Et voilà !
    Grâce à l'opérateur « >> », les données de iss sont envoyées vers AdresseReception.
    Comme c'est un unsigned long, les données sont interprétées comme un entier, et non pas comme une suite de caractères.
    Mais on a bien précisé avant qu'il fallait le lire sous sa forme hexadécimale au lieu de décimale, à l'aide du manipulateur « std::hex() ».

    Si tu as d'autres questions, n'hésite pas.
    Au fait, tu connais « std::cin », « std::cout », « std::cerr » et « std::endl » ?

  7. #7
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut À méditer avant toute considération
    Tout compte fait, question prioritaire…
    Tu veux faire du C ou du C++ ?

  8. #8
    Nouveau membre du Club
    Inscrit en
    Mars 2010
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Mars 2010
    Messages : 62
    Points : 33
    Points
    33
    Par défaut
    Merci beaucoup pour votre réponse.

    Au fait, tu connais « std::cin », « std::cout », « std::cerr » et « std::endl » ?
    Oui je connais enfin pa sle std::cerr.

    En faite au mieux j'aimerais faire du C++ je m'y emploi en tout cas.

  9. #9
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Ok.
    Je te posais cette question parce que dans ton code, il y a des instructions C dont l'équivalent C++ existe.

    Par exemple, tous tes transtypages :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xmlChar* chaine = (xmlChar*) "toto";
    En passant, l'auteur a prévu le coup, s'il n'y a que des caractères ASCII :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xmlChar* chaine = BAD_CAST "toto";
    Mais bon, c'est une macro qui se contente de faire un cast…
    En C++, il faudrait écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xmlChar* chaine = static_cast<xmlChar*>("toto");

    Note que si la chaîne contient des caractères non-ASCII (les lettres accentuées ou « exotiques », par exemple), il faut utiliser les fonctions fournies par la bibliothèque, dans le module « xmlstring » si ma mémoire est bonne.

    Lorsque tu veux écrire sur la sortie d'erreur standard, tu utilises une fonction C :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include <cstdio>
     
    fprintf(stderr, "Erreur !\n");
    L'équivalent C++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include <iostream>
     
    std::cerr << "Erreur !" << std::endl;
    Ce n'est pas interdit de mixer les deux méthodes, mais ce n'est pas une bonne pratique pour autant.
    Il suffit que les deux ne soient pas correctement synchronisées pour obtenir un comportement incohérent.

    Au fait, tu connais « libxml++ » ?
    http://libxmlplusplus.sourceforge.net/

  10. #10
    Nouveau membre du Club
    Inscrit en
    Mars 2010
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Mars 2010
    Messages : 62
    Points : 33
    Points
    33
    Par défaut
    Merci pour votre réponse, non je ne connais pas du tout cette librairie je vai regarder.

    EN tout cas je vais essayer d'appliquer ce que vous m'avez dit, j'ai déja fait des modifications et je vais essayer de comprendre vraiment comment je vais faire pour l'histoire du n->content.

    Merci beaucup pour votre aide

  11. #11
    Nouveau membre du Club
    Inscrit en
    Mars 2010
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Mars 2010
    Messages : 62
    Points : 33
    Points
    33
    Par défaut
    Excusez moi encore de vous déranger.

    Mais en mettant le code proposé j'ai l'impression qu'il ne réunssit pas a faire le cast car il me met comme erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     error C2296
    : '>>' : illegal, left operand has type 'struct _xmlNode *'
     error C2297
    : '>>' : illegal, right operand has type 'class std::ios_base &(__cdecl *)(class std::ios_base &)'
    error C2440
    : 'static_cast' : cannot convert from 'unsigned char *' to 'char *'
            Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    Error executing cl.exe.
    J'avous que je ne comprend pas très bien...

  12. #12
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Arf, au temps pour moi…

    La solution est donnée dans la dernière erreur :
    Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    On ne peut pas utiliser le « static_cast » dans ce cas-là :
    http://cpp.developpez.com/faq/cpp/?p...s#DIVERS_casts

    On a donc 3 possibilités pour faire la conversion :
    • reinterpret_cast : même syntaxe que pour « static_cast », c'est juste la sémantique qui est différente ;
    • C-style cast : ce que tu utilisais avant ou, mieux, la macro « BAD_CAST » prévue à cet effet ;
    • function-style cast : une fonction qui prend en paramètre un objet du type d'origine, qui retourne un objet du type cible, et qui est censée faire la conversion du premier vers le second.

  13. #13
    Nouveau membre du Club
    Inscrit en
    Mars 2010
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Mars 2010
    Messages : 62
    Points : 33
    Points
    33
    Par défaut
    J'ai fais un reinterpret_cast et ça fonctionne!

    Mon proramme fonctionne parfatement je suis vraiment très très contente. Cafait des semaines que j'étais bloqué.

    Et en plus j'ai compris pourquoi ça ne fonctionnais pas et j'ai compris un peu plus le C++ et les cast.

    Je vous remercie infiniment pour votre aide TRES précieuse et votre patiente!

    Merci beaucoup beaucoup!

    Passez une bonne après midi et bon weeken!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [JAXB] Créer Fichier XML en Java (problème de parsing)
    Par rogersdrejordan dans le forum Format d'échange (XML, JSON...)
    Réponses: 5
    Dernier message: 13/06/2012, 20h02
  2. [libxml2] écrire un fichier XML en C
    Par floopi51 dans le forum XML
    Réponses: 0
    Dernier message: 14/12/2009, 12h11
  3. [SAX] Problème lecture fichier xml
    Par BernardT dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 07/07/2005, 19h11
  4. Valider fichier XML : problème avec la DTD
    Par SkIllz2k dans le forum Valider
    Réponses: 2
    Dernier message: 26/04/2005, 18h15
  5. Réponses: 2
    Dernier message: 01/06/2004, 13h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo