Bonjour à tous! Bon, mon problème me dépasse un petit peux...
J'ai créer une classe qui me permet de gérer des fichier XML selon mon besoin. Pas de problème de ce côté là. Comme vous allé le voire, j'utilise un TXmlDocument créer dynamiquement pour éditer mes fichier XML.
Voici un partie du code source de ma classe :
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 //--------------------------------------------------------------------------- #ifndef TXmlCreatorH #define TXmlCreatorH #include <vcl.h> #include <msxmldom.hpp> #include <XMLDoc.hpp> #include <xmldom.hpp> #include <XMLIntf.hpp> //--------------------------------------------------------------------------- class TXmlCreator { public : //Constructeur. Il permet de récupérer les informations pour la création du fichier XML __fastcall TXmlCreator( AnsiString lProcess, AnsiString lOutPath, AnsiString lRoot, AnsiString lLevel, AnsiString lFrom); //Destructeur __fastcall ~TXmlCreator(void); //Méthode appelé pour l'ajout d'image void __fastcall addImageToLine(AnsiString idLine, AnsiString imagePath, int errorCode, AnsiString info); void __fastcall addImageToLine(AnsiString imagePath, int errorCode, AnsiString info); void __fastcall saveXmlFile(void); private : //Méthode permettant la création d'un fichier XML void __fastcall createFile(void); //Méthode qui permet de créer les noeud principaux void __fastcall createBaseNode(void); //Méthodes appelé pour ajouter une ligne AnsiString __fastcall findIdImage(AnsiString imagePath); int __fastcall indexOfLineFromId(AnsiString idLine); void __fastcall addLine(AnsiString idLine); //Attribut utilisé pour la création dynamique d'un TXMLDocument TXMLDocument *XMLDoc; _di_IXMLDocument iXML; _di_IXMLNode node; //Attribut utilisé pour récupérer les informations nécessaire pour créer le fichier XML AnsiString mProcess; AnsiString mOutPath; AnsiString mRoot; AnsiString mLevel; AnsiString mFrom; int mTotal; }; #endif
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
72
73
74
75
76
77
78
79 //Constructeur __fastcall TXmlCreator::TXmlCreator( AnsiString lProcess, AnsiString lOutPath, AnsiString lRoot, AnsiString lLevel, AnsiString lFrom) { /* **Lorsque l'on créer une instance d'un TXmlcréator, il faut lui passer 5 paramètres : ** ** -OutPath : qui représente le chemin d'accès du fichier xml à créer ** -Process : qui représente le chemin d'accès au script ** -Root : qui représente le chemin de la source utilisé pour la création du fichier ** -Level : qui représente le niveau de priorité du traitement (Low, Normal, High) ** -From : qui représente le type de source (base, socket...) ** ** La variable total représente le nombre de ligne dans le fichier xml. ** Elle s'incrémente automatiquement à l'ajout d'une ligne. */ mOutPath = lOutPath; mProcess = lProcess; mRoot = lRoot; mLevel = lLevel; mFrom = lFrom; mTotal = 0; //Appel la méthode privée createFile(). createFile(); /* **Après avoir créer le fichier xml : ** ** -On créer une nouvelle instance d'un TCMLDocument ** -On lui attribut un _di_IXMLdocument ** -On charge le fichier xml que l'on a préalablement créé. ** -On affecte le noeud principale à un _di_IXMLnode */ XMLDoc = new TXMLDocument(""); //instance d'un TCMLDocument. XMLDoc->GetInterface(iXML); //attribution d'un _di_IXMLdocument. iXML->LoadFromFile(mOutPath); //chargement du fichier. node = iXML->DocumentElement; //affectation du noeud principale. createBaseNode(); //Appel la méthode privée createBaseNode(). } //Destructeur __fastcall TXmlCreator::~TXmlCreator(void) { if (XMLDoc) delete XMLDoc; XMLDoc = NULL; //A la destruction de l'objet, on désallou le TXMLDocument } void __fastcall TXmlCreator::createFile(void) { /* **Cette méthode s'occupe de créer le fichier xml sur le disque, à l'endroit désiré. **Elle créer aussi la balise principale <Setup> */ TFileStream* xmlFile = new TFileStream( mOutPath, fmCreate); //création du fichier char *writeFileBuffer = new char[16]; //création d'un buffer pour écrire dans le fichier writeFileBuffer = "<setup>\n</setup>"; //on rempli le buffer affin de créer manuellement une balise xmlFile->WriteBuffer(writeFileBuffer, 16); //on écri le contenu du buffer dans le fichier if (xmlFile) delete xmlFile; xmlFile = NULL; //on désallou la mémoire utilisé pour la fonction if (writeFileBuffer) delete writeFileBuffer; writeFileBuffer = NULL; } void __fastcall TXmlCreator::createBaseNode(void) { /* **Le but de cette méthode est de créer les noeud principaux (root, from, level, total, lines) */ node->AddChild("info", 0); node->AddChild("lines", 1); //Création du noeud info node->ChildNodes->Nodes[0]->SetAttribute("process",mProcess); //Ajout de l'atribut process qui prend la valeur mProcess node->ChildNodes->Nodes[0]->SetAttribute("root",mRoot); node->ChildNodes->Nodes[0]->SetAttribute("from",mFrom); node->ChildNodes->Nodes[0]->SetAttribute("level",mLevel); node->ChildNodes->Nodes[0]->SetAttribute("total",mTotal); }
Je n'ai pas écris la totalité du fichier 'TXmlCreator.cpp' par souci de clarté. Si mon code vous intéresse, demandé le moi!
Le problème ce situe au niveau du destructeur.J'ai une violation d'accès mémoire au moment du delete.
J'ai commencé par voir au niveau de la documentation du TXmlDocument, et je suis tombé la dessus :
Citation : Documentation TXmlDocument
Citation : Documentation TXmlDocumentDisposes of a TXMLDocument object.
__fastcall virtual ~TXMLDocument(void);
Description
It is not necessary to explicitly free a TXMLDocument component. If the component is created with an Owner, that Owner handles the task of freeing the document. If the component is created without an Owner, it is freed automatically when the reference count on its IXMLDocument interface drops to zero.
Si je comprend bien, ces paragraphes disent que le TXmlDocument ce fait détruire par son owner si il en possède un (le mien n'en a pas) et que dans le cas où il n'en à pas, il ce détruit lorsque son compteur d'interface arrivais à 0.When TXMLDocument is created without an Owner, it behaves like an interfaced object. That is, when all references to its interface are released, the TXMLDocument instance is automatically freed. When TXMLDocument is created with an Owner, however, it behaves like any other component, and is freed by its Owner. When you add a TXMLDocument component from the component palette to a form or data module, it is automatically created with an Owner. When the TXMLDocument component is created using the global LoadXMLDocument function (or by a function that the XML Data Binding wizard generates to return the root node of the document), the function creates a TXMLDocument instance without an Owner.
Là je me suis dis cool, je n'ai qu'à supprimer l'interface iXML! J'ai trouvé une méthode 'release()' qui appartient à iXml, et qui renvoie le nombre d'interface restante! Le problème c'est que cette méthode me renvoie 1, et non pas 0. Il y a donc encore une interface.
Je suis pas très doué en programmation mais je trouvais que faire comme ceci était un peu 'moyen' :-°
Du coup j'ai cherché sur internet, je suis tombé sur un post intéressant :
http://www.developpez.net/forums/d30.../txmldocument/
Bon, alors là, ça me dépasse COMPLÈTEMENT!
Quelqu'un pourrais me filer un petit coup de main?
Merci à vous!
Partager