Sign in Join
Wiki copytemporary

XML Tutorial/fr: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Introduction
22
33Le langage de balises extensible (*eXtensible Markup Language*) est un langage recommandé par le [W3C](http://www.w3.org/) créé pour l'échange d'informations entre différents systèmes. Il propose le stockage d'informations sous forme de texte. Les langages modernes d'échanges de données comme le XHTML, tout comme la plupart des technologies WebServices, sont fondés sur le XML.
44
55Il existe actuellement un ensemble d'unités qui offrent le support du XML à Free Pascal. Ces unités appelées *XMLRead*, *XMLWrite* et *DOM* font partie de la *Free Component Library* (FCL) du compilateur Free Pascal. La FCL est déjà sur le chemin de recherche par défaut du compilateur de Lazarus : vous n'avez donc qu'à ajouter ces unités à votre clause *uses* pour obtenir l'accès au XML. La FCL n'étant que partiellement documentée à ce jour (mai 2015), ce petit tutoriel vise à introduire l'utilisation minimale du XML en utilisant ces unités.
66
77Le DOM XML (*Document Object Model*) est un ensemble d'objets standardisés offrant une interface similaire pour l'utilisation du XML avec différents langages et systèmes. Le standard spécifie uniquement les méthodes, propriétés et autres parties d'interface de l'objet, laissant l'implémentation libre pour les différents langages. La FCL supporte totalement le [XML DOM 2.0](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/) et un sous-ensemble du [XML DOM 3.0](http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/) détaillé [[dom|ici]].
88
99## Exemples
1010
1111Ci-dessous figure une série d'exemples de manipulations de données XML dont la complexité va en croissant.
1212
1313## Unités dans la clause *uses* : Unicode ou Ansi
1414
1515FPC est accompagné d'unités XML fondées sur des routines dont le codage correspond à la norme ANSI si bien que les résultats sur différentes plateformes peuvent ne pas être homogènes et en particulier non Unicode. Lazarus fournit un ensemble complémentaire d'unités XML avec le paquet *LazUtils* qui supporte totalement le codage Unicode UTF-8 pour toutes les plateformes. Toutes ces unités sont compatibles : pour passer de l'une à l'autre, il suffit d'adapter la clause *uses* en conséquence.
1616
1717Les unités proposées par FPC pour le traitement du XML sont (chaînes encodées selon l'encodage du système) :
1818
19-`   `*`DOM`*\
20-`   `*`XMLRead`*\
21-`   `*`XMLWrite`*\
22-`   `*`XMLCfg`*\
23-`   `*`XMLUtils`*\
24-`   `*`XMLStreaming`*` `
19+```text
20+ DOM
21+ XMLRead
22+ XMLWrite
23+ XMLCfg
24+ XMLUtils
25+ XMLStreaming
26+```
2527
2628Les unités proposées par Lazarus pour le traitement du XML sont (chaînes avec support de l'Unicode UTF-8 sur toutes les plateformes) :
2729
28-`   `*`laz2_DOM`*\
29-`   `*`laz2_XMLRead`*\
30-`   `*`laz2_XMLWrite`*\
31-`   `*`laz2_XMLCfg`*\
32-`   `*`laz2_XMLUtils`*\
33-`   `*`laz_XMLStreaming`*` `
30+```text
31+ laz2_DOM
32+ laz2_XMLRead
33+ laz2_XMLWrite
34+ laz2_XMLCfg
35+ laz2_XMLUtils
36+ laz_XMLStreaming
37+```
3438
3539Toutes ces unités ne sont pas nécessaires pour chacun des exemples qui suivent. Vous aurez toutefois toujours besoin de l'unité *DOM* (ou *laz2_DOM*) dans la mesure où elle définit plusieurs types dont *TXMLDocument*.
3640
3741### Lire un nœud de texte
3842
3943Pour les programmeurs Delphi : notez que lorsque vous travaillez avec *TXMLDocument*, le texte à l'intérieur d'un nœud est considéré comme un nœud de texte séparé. Vous devez donc accéder à une valeur texte d'un nœud comme à un nœud séparé.
4044
4145Par exemple, considérez le XML suivant :
4246
4347``` xml
4448 <?xml version="1.0"?>
4549 <request>
4650 <request_type>PUT_FILE</request_type>
4751 <username>123</username>
4852 <password>abc</password>
4953 </request>
5054```
5155
5256L'exemple de code suivant montre la bonne et la mauvaise façon d'obtenir la valeur du texte du nœud :
5357
5458``` pascal
5559 var
5660 PassNode: TDOMNode;
5761 Doc: TXMLDocument;
5862 begin
5963 // Lit le fichier xml depuis le disque
6064 ReadXMLFile(Doc, 'c:\xmlfiles\test.xml');
6165 // Récupère le nœud "password"
6266 PassNode := Doc.DocumentElement.FindNode('password');
6367 // Ecrit la valeur du nœud sélectionné
6468 WriteLn(PassNode.NodeValue); // ce sera vide
6569 // Le texte du nœud est réellement un nœud enfant distinct
6670 WriteLn(PassNode.FirstChild.NodeValue); // affiche correctement "abc"
6771```
6872
6973### Afficher les noms des nœuds
7074
7175L'exemple suivant montre comment afficher les noms des nœud dans un *TMemo* placé sur une fiche.
7276
7377Ci-dessous le fichier XML appelé 'C:\Programs\test.xml' :
7478
7579``` xml
7680 <?xml version="1.0"?>
7781 <images directory="mydir">
7882 <imageNode URL="graphic.jpg" title="">
7983 <Peca DestinoX="0" DestinoY="0">Pecacastelo.jpg1.swf</Peca>
8084 <Peca DestinoX="0" DestinoY="86">Pecacastelo.jpg2.swf</Peca>
8185 </imageNode>
8286 </images>
8387```
8488
8589Et ci-après le code Pascal pour exécuter la tâche :
8690
8791``` pascal
8892 var
8993 Document: TXMLDocument;
9094 i, j: Integer;
9195 begin
9296 ReadXMLFile(Document, 'C:\Programs\test.xml');
9397 Memo.Lines.Clear;
9498 with Document.DocumentElement.ChildNodes do
9599 begin
96100 for i := 0 to (Count - 1) do
97101 begin
98102 Memo.Lines.Add(Item[i].NodeName + ' ' + Item[i].Attributes.Item[0].NodeValue);
99103 for j := 0 to (Item[i].ChildNodes.Count - 1) do
100104 begin
101105 Memo.Lines.Add(Item[i].ChildNodes.Item[j].NodeName + ' '
102106 + Item[i].ChildNodes.Item[j].FirstChild.NodeValue);
103107 end;
104108 end;
105109 end;
106110 Document.Free;
107111 end;
108112```
109113
110114Ce qui affichera:
111115
112116 imageNode graphic.jpg
113117 Peca Pecacastelo.jpg1.swf
114118 Peca Pecacastelo.jpg1.swf
115119
116120### Peupler un TreeView avec XML
117121
118122Une utilisation courante des fichers XML est de les analyser et d'afficher leur contenu sous forme d'arborescence. Pour ce faire, vous pouvez utiliser le composant *TTreeView* présent sous l'onglet *Common Controls* de Lazarus.
119123
120124La procédure ci-dessous va prendre un document XML précédemment chargé depuis un fichier ou généré par code, avant de peupler un *TreeView* avec son contenu. La légende de chaque nœud de l'arbre sera le contenu du premier attribut de chaque nœud du document XML.
121125
122126``` pascal
123127procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument);
124128var
125129 iNode: TDOMNode;
126130
127131 procedure ProcessNode(Node: TDOMNode; TreeNode: TTreeNode);
128132 var
129133 cNode: TDOMNode;
130134 s: string;
131135 begin
132136 if Node = nil then Exit; // Stoppe si on a atteint une feuille
133137
134138 // Ajoute un nœud à l'arbre s'il existe
135139 if Node.HasAttributes and (Node.Attributes.Length>0) then
136140 s := Node.Attributes[0].NodeValue
137141 else
138142 s := '';
139143 TreeNode := tree.Items.AddChild(TreeNode, s);
140144
141145
142146 // Va au nœud enfant
143147 cNode := Node.ChildNodes.Item[0];
144148
145149 // Traite tous les nœuds enfants
146150 while cNode <> nil do
147151 begin
148152 ProcessNoDe(cNode, TreeNode);
149153 cNode := cNode.NextSibling;
150154 end;
151155 end;
152156
153157begin
154158 iNode := XMLDoc.DocumentElement.ChildNodes.Item[0];
155159 while iNode <> nil do
156160 begin
157161 ProcessNode(iNode, nil); // Procédure récursive
158162 iNode := iNode.NextSibling;
159163 end;
160164end;
161165```
162166
163167### Modifier un document XML
164168
165169La première chose à se rappeler est que *TDOMDocument* est le "handle" vers le *DOM*. Vous pouvez obtenir une instance de cette classe en créant ou en chargeant un document XML.
166170
167171D'un autre côté, les nœuds ne peuvent être créés comme des objets classiques. Vous *devez* utiliser les méthodes mises à disposition par *TDOMDocument* pour les créer puis utiliser d'autres méthodes pour les placer correctement dans l'arbre. Cela est dû au fait que les nœuds doivent être "possédés" par un document spécifique du *DOM*.
168172
169173Ci-dessous sont indiquées quelques méthodes particulièrement utiles de *TDOMDocument* :
170174
171175``` pascal
172176 function CreateElement(const tagName: DOMString): TDOMElement; virtual;
173177 function CreateTextNode(const data: DOMString): TDOMText;
174178 function CreateCDATASection(const data: DOMString): TDOMCDATASection;
175179 virtual;
176180 function CreateAttribute(const name: DOMString): TDOMAttr; virtual;
177181```
178182
179183*CreateElement* crée un nouvel élément.
180184
181185*CreateTextNode* crée un noeud texte.
182186
183187*CreateAttribute* crée un noeud attribut.
184188
185189*CreateCDATASection* crée une section *CDATA* : les caractères de marquage particuliers à XML tels que \<\> ne sont pas intrepréts au sein d'une section *CDATA*.
186190
187191Une façon plus facile de manipuler les attributs consiste à utiliser la méthode *TDOMElement.SetAttribute* (elle est par ailleurs la propriété par défaut de *TDOMElement*) :
188192
189193``` pascal
190194// these two statements are equivalent
191195Element.SetAttribute('name', 'value');
192196Element['name'] := 'value';
193197```
194198
195199Et ci-après un exemple de méthode qui localise l'élément sélectionné dans un *TTreeView* avant d'insérer un nœud enfant au document XML qu'il représente. Le *TreeView* doit être précédement rempli avec le contenu du fichier XML en utilisant la [[XML Tutorial|fonction XML2Tree]].
196200
197201``` pascal
198202procedure TForm1.actAddChildNode(Sender: TObject);
199203var
200204 Posicao: Integer;
201205 NovoNo: TDomNode;
202206begin
203207 {*******************************************************************
204208 * Détection de l'élément sélectionné
205209 *******************************************************************}
206210 if TreeView1.Selected = nil then Exit;
207211
208212 if TreeView1.Selected.Level = 0 then
209213 begin
210214 Posicao := TreeView1.Selected.Index;
211215
212216 NovoNo := XMLDoc.CreateElement('item');
213217 TDOMElement(NovoNo).SetAttribute('nome', 'Item');
214218 TDOMElement(NovoNo).SetAttribute('arquivo', 'Arquivo');
215219 XMLDoc.DocumentElement.ChildNodes.Item[Posicao].AppendChild(NovoNo);
216220
217221 {*******************************************************************
218222 * Mise à jour du TreeView
219223 *******************************************************************}
220224 TreeView1.Items.Clear;
221225 XML2Tree(TreeView1, XMLDoc);
222226 end
223227 else if TreeView1.Selected.Level >= 1 then
224228 begin
225229 {*******************************************************************
226230 * Cette fonction n'est opérante qu'au premier niveau de l'arbre,
227231 * mais peut facilement être modifiée pour fonctionner avec plusieurs niveaux
228232 *******************************************************************}
229233 end;
230234end;
231235```
232236
233237### Créer un TXMLDocument à partir d'une chaîne
234238
235239Étant donné un fichier XML dans *MyXmlString*, le code suivant va créer son *DOM* :
236240
237241``` pascal
238242Var
239243 S : TStringStream;
240244 XML : TXMLDocument;
241245
242246begin
243247 S:= TStringStream.Create(MyXMLString);
244248 Try
245249 S.Position:=0;
246250 XML:=Nil;
247251 ReadXMLFile(XML,S); // Document XML complet
248252 // Autre possibilité
249253 ReadXMLFragment(AParentNode,S); // Lit uniquement un fragment XML.
250254 Finally
251255 S.Free;
252256 end;
253257end;
254258```
255259
256260## Liens Externes
257261
258262- [W3Schools](http://www.w3schools.com/xml/default.asp) Tutoriel XML
259263
260264- [Thomas Zastrow article](http://www.thomas-zastrow.de/texte/fpcxml/index.php) FPC et XML
261265
262266---
263267*From the Free Pascal wiki, page "XML Tutorial/fr", as it stood on 2020-03-02 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history