Difference between revisions of "XML Tutorial/fr"

From Free Pascal wiki
Jump to navigationJump to search
m (Fixed syntax highlighting)
 
(19 intermediate revisions by one other user not shown)
Line 5: Line 5:
 
Le langage de balises extensible (''eXtensible Markup Language'') est un langage recommandé par le [http://www.w3.org/ W3C] 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.
 
Le langage de balises extensible (''eXtensible Markup Language'') est un langage recommandé par le [http://www.w3.org/ W3C] 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.
  
Il existe actuellement un ensemble d'unités qui offrent le support du XML au 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.
+
Il 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.
  
 
Le 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 [http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ XML DOM 2.0] et un sous-ensemble du [http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/ XML DOM 3.0] détaillé [[dom|ici]].
 
Le 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 [http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ XML DOM 2.0] et un sous-ensemble du [http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/ XML DOM 3.0] détaillé [[dom|ici]].
Line 11: Line 11:
 
== Exemples ==
 
== Exemples ==
  
Ci-dessous se trouve une liste d'exemples de manipulation de données XML qui croissent en complexité.
+
Ci-dessous figure une série d'exemples de manipulations de données XML dont la complexité va en croissant.
 +
 
 +
== Unités dans la clause ''uses'' : Unicode ou Ansi ==
 +
 
 +
FPC 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.
 +
 
 +
Les unités proposées par FPC pour le traitement du XML sont (chaînes encodées selon l'encodage du système) :
 +
 
 +
    ''DOM''
 +
    ''XMLRead''
 +
    ''XMLWrite''
 +
    ''XMLCfg''
 +
    ''XMLUtils''
 +
    ''XMLStreaming''
 +
 
 +
Les 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) :
 +
 
 +
    ''laz2_DOM''
 +
    ''laz2_XMLRead''
 +
    ''laz2_XMLWrite''
 +
    ''laz2_XMLCfg''
 +
    ''laz2_XMLUtils''
 +
    ''laz_XMLStreaming''
 +
 
 +
Toutes 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''.  
  
 
=== Lire un nœud de texte ===
 
=== Lire un nœud de texte ===
  
Pour les programmeurs Delphi: notez que lorsque vous travaillez avec ''TXMLDocument'', le texte à l'intérieur d'un ''Node'' est considéré comme un ''Node TEXT'' séparé.  Vous devez donc accéder à une valeur texte de nœud comme à un nœud séparé.
+
Pour 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é.
  
 
Par exemple, considérez le  XML suivant :
 
Par exemple, considérez le  XML suivant :
Line 28: Line 52:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
L'exemple de code suivant montre la bonne et la mauvaise façon d'obtenir la valeur du nœud texte :
+
L'exemple de code suivant montre la bonne et la mauvaise façon d'obtenir la valeur du texte du nœud :
  
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
  var
 
  var
 
   PassNode: TDOMNode;
 
   PassNode: TDOMNode;
Line 63: Line 87:
 
Et ci-après le code Pascal pour exécuter la tâche :
 
Et ci-après le code Pascal pour exécuter la tâche :
  
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
  var
 
  var
 
   Document: TXMLDocument;
 
   Document: TXMLDocument;
Line 98: Line 122:
 
Une 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.
 
Une 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.
  
La fonction ci-dessous va prendre un document XML précédement 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.
+
La 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.
  
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument);
 
procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument);
 
var
 
var
Line 108: Line 132:
 
   var
 
   var
 
     cNode: TDOMNode;
 
     cNode: TDOMNode;
 +
    s: string;
 
   begin
 
   begin
 
     if Node = nil then Exit; // Stoppe si on a atteint une feuille
 
     if Node = nil then Exit; // Stoppe si on a atteint une feuille
 +
 +
    // Ajoute un nœud à l'arbre s'il existe
 +
    if Node.HasAttributes and (Node.Attributes.Length>0) then
 +
      s := Node.Attributes[0].NodeValue
 +
    else
 +
      s := '';
 +
    TreeNode := tree.Items.AddChild(TreeNode, s);
 
      
 
      
    // Ajoute un noeud à l'arbre
 
    TreeNode := tree.Items.AddChild(TreeNode, Node.Attributes[0].NodeValue);
 
  
 
     // Va au nœud enfant
 
     // Va au nœud enfant
 
     cNode := Node.ChildNodes.Item[0];
 
     cNode := Node.ChildNodes.Item[0];
  
     // Traite tous les nœud enfants
+
     // Traite tous les nœuds enfants
 
     while cNode <> nil do
 
     while cNode <> nil do
 
     begin
 
     begin
Line 139: Line 169:
 
La 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.
 
La 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.
  
D'un autre côté, les nœud ne peuvent être créés comme des objets classiques.  Vous *devez* utiliser les méthodes mises à disposition par ''TDOMDocument'' pour les créer : ces méthodes utilisent les autres méthodes pour les mettre à la bonne place dans l'arbre. Cela est dû au fait que les nœud doivent être "possédés" par un document spécifique du ''DOM''.
+
D'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''.
  
Ci-dessous sont indiquées quelques méthodes courantes de ''TDOMDocument'' :
+
Ci-dessous sont indiquées quelques méthodes particulièrement utiles de ''TDOMDocument'' :
  
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
   function CreateElement(const tagName: DOMString): TDOMElement; virtual;
 
   function CreateElement(const tagName: DOMString): TDOMElement; virtual;
 
   function CreateTextNode(const data: DOMString): TDOMText;
 
   function CreateTextNode(const data: DOMString): TDOMText;
Line 151: Line 181:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Et ici un exemple de méthode qui localise l'élément sélectionné dans un ''TTreeView'' et qui insère 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 [[Networking#Populating a TreeView with XML|fonction XML2Tree]].
+
''CreateElement'' crée un nouvel élément.
 +
 
 +
''CreateTextNode'' crée un noeud texte.
 +
 
 +
''CreateAttribute'' crée un noeud attribut.
 +
 
 +
''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''.
 +
 
 +
Une 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'') :
 +
 
 +
<syntaxhighlight lang=pascal>
 +
// these two statements are equivalent
 +
Element.SetAttribute('name', 'value');
 +
Element['name'] := 'value';
 +
</syntaxhighlight>
 +
 
 +
Et 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#Populating a TreeView with XML|fonction XML2Tree]].
  
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
procedure TForm1.actAddChildNode(Sender: TObject);
 
procedure TForm1.actAddChildNode(Sender: TObject);
 
var
 
var
Line 191: Line 237:
 
=== Créer un TXMLDocument à partir d'une chaîne ===
 
=== Créer un TXMLDocument à partir d'une chaîne ===
  
Etant donné un fichier XML dans MyXmlString, le code suivant va créer son DOM:
+
Étant donné un fichier XML dans ''MyXmlString'', le code suivant va créer son ''DOM'' :
  
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
Var
 
Var
 
   S : TStringStream;
 
   S : TStringStream;
Line 204: Line 250:
 
     XML:=Nil;
 
     XML:=Nil;
 
     ReadXMLFile(XML,S); // Document XML complet
 
     ReadXMLFile(XML,S); // Document XML complet
     // Alternatively:
+
     // Autre possibilité
 
     ReadXMLFragment(AParentNode,S); // Lit uniquement un fragment XML.  
 
     ReadXMLFragment(AParentNode,S); // Lit uniquement un fragment XML.  
 
   Finally
 
   Finally

Latest revision as of 02:42, 2 March 2020

Deutsch (de) English (en) español (es) français (fr) magyar (hu) Bahasa Indonesia (id) italiano (it) 日本語 (ja) 한국어 (ko) português (pt) русский (ru) 中文(中国大陆)‎ (zh_CN)

Introduction

Le langage de balises extensible (eXtensible Markup Language) est un langage recommandé par le W3C 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.

Il 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.

Le 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 et un sous-ensemble du XML DOM 3.0 détaillé ici.

Exemples

Ci-dessous figure une série d'exemples de manipulations de données XML dont la complexité va en croissant.

Unités dans la clause uses : Unicode ou Ansi

FPC 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.

Les unités proposées par FPC pour le traitement du XML sont (chaînes encodées selon l'encodage du système) :

   DOM
   XMLRead
   XMLWrite
   XMLCfg
   XMLUtils
   XMLStreaming 

Les 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) :

   laz2_DOM
   laz2_XMLRead
   laz2_XMLWrite
   laz2_XMLCfg
   laz2_XMLUtils
   laz_XMLStreaming 

Toutes 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.

Lire un nœud de texte

Pour 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é.

Par exemple, considérez le XML suivant :

 <?xml version="1.0"?>
 <request>
   <request_type>PUT_FILE</request_type>
   <username>123</username>
   <password>abc</password>
 </request>

L'exemple de code suivant montre la bonne et la mauvaise façon d'obtenir la valeur du texte du nœud :

 var
  PassNode: TDOMNode;
  Doc:      TXMLDocument;
 begin
  // Lit le fichier xml depuis le disque
  ReadXMLFile(Doc, 'c:\xmlfiles\test.xml');
  // Récupère le nœud "password"
  PassNode := Doc.DocumentElement.FindNode('password');
  // Ecrit la valeur du nœud sélectionné
  WriteLn(PassNode.NodeValue); // ce sera vide
  // Le texte du nœud est réellement  un nœud enfant distinct
  WriteLn(PassNode.FirstChild.NodeValue); // affiche correctement "abc"

Afficher les noms des nœuds

L'exemple suivant montre comment afficher les noms des nœud dans un TMemo placé sur une fiche.

Ci-dessous le fichier XML appelé 'C:\Programs\test.xml' :

 <?xml version="1.0"?>
 <images directory="mydir">
  <imageNode URL="graphic.jpg" title="">
    <Peca DestinoX="0" DestinoY="0">Pecacastelo.jpg1.swf</Peca>
    <Peca DestinoX="0" DestinoY="86">Pecacastelo.jpg2.swf</Peca>
  </imageNode>
 </images>

Et ci-après le code Pascal pour exécuter la tâche :

 var
   Document: TXMLDocument;
   i, j: Integer;
 begin
   ReadXMLFile(Document, 'C:\Programs\test.xml');
   Memo.Lines.Clear;
   with Document.DocumentElement.ChildNodes do
   begin
     for i := 0 to (Count - 1) do
     begin
       Memo.Lines.Add(Item[i].NodeName + ' ' + Item[i].Attributes.Item[0].NodeValue);
       for j := 0 to (Item[i].ChildNodes.Count - 1) do
       begin
         Memo.Lines.Add(Item[i].ChildNodes.Item[j].NodeName + ' '
          + Item[i].ChildNodes.Item[j].FirstChild.NodeValue);
       end;
     end;
   end;
   Document.Free;
 end;

Ce qui affichera:

imageNode graphic.jpg
Peca Pecacastelo.jpg1.swf
Peca Pecacastelo.jpg1.swf

Peupler un TreeView avec XML

Une 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.

La 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.

procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument);
var
  iNode: TDOMNode;

  procedure ProcessNode(Node: TDOMNode; TreeNode: TTreeNode);
  var
    cNode: TDOMNode;
    s: string;
  begin
    if Node = nil then Exit; // Stoppe si on a atteint une feuille

    // Ajoute un nœud à l'arbre s'il existe
    if Node.HasAttributes and (Node.Attributes.Length>0) then
      s := Node.Attributes[0].NodeValue
    else
      s := ''; 
    TreeNode := tree.Items.AddChild(TreeNode, s);
    

    // Va au nœud enfant
    cNode := Node.ChildNodes.Item[0];

    // Traite tous les nœuds enfants
    while cNode <> nil do
    begin
      ProcessNoDe(cNode, TreeNode);
      cNode := cNode.NextSibling;
    end;
  end;
    
begin
  iNode := XMLDoc.DocumentElement.ChildNodes.Item[0];
  while iNode <> nil do
  begin
    ProcessNode(iNode, nil); // Procédure récursive
    iNode := iNode.NextSibling;
  end;
end;

Modifier un document XML

La 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.

D'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.

Ci-dessous sont indiquées quelques méthodes particulièrement utiles de TDOMDocument :

   function CreateElement(const tagName: DOMString): TDOMElement; virtual;
   function CreateTextNode(const data: DOMString): TDOMText;
   function CreateCDATASection(const data: DOMString): TDOMCDATASection;
     virtual;
   function CreateAttribute(const name: DOMString): TDOMAttr; virtual;

CreateElement crée un nouvel élément.

CreateTextNode crée un noeud texte.

CreateAttribute crée un noeud attribut.

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.

Une 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) :

// these two statements are equivalent
Element.SetAttribute('name', 'value');
Element['name'] := 'value';

Et 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 fonction XML2Tree.

procedure TForm1.actAddChildNode(Sender: TObject);
var
  Posicao: Integer;
  NovoNo: TDomNode;
begin
  {*******************************************************************
  *  Détection de l'élément sélectionné
  *******************************************************************}
  if TreeView1.Selected = nil then Exit;

  if TreeView1.Selected.Level = 0 then
  begin
    Posicao := TreeView1.Selected.Index;

    NovoNo := XMLDoc.CreateElement('item');
    TDOMElement(NovoNo).SetAttribute('nome', 'Item');
    TDOMElement(NovoNo).SetAttribute('arquivo', 'Arquivo');
    XMLDoc.DocumentElement.ChildNodes.Item[Posicao].AppendChild(NovoNo);

    {*******************************************************************
    *  Mise à jour du TreeView
    *******************************************************************}
    TreeView1.Items.Clear;
    XML2Tree(TreeView1, XMLDoc);
  end
  else if TreeView1.Selected.Level >= 1 then
  begin
    {*******************************************************************
    *  Cette fonction n'est opérante qu'au premier niveau de l'arbre,
    *  mais peut facilement être modifiée pour fonctionner avec plusieurs niveaux
    *******************************************************************}
  end;
end;

Créer un TXMLDocument à partir d'une chaîne

Étant donné un fichier XML dans MyXmlString, le code suivant va créer son DOM :

Var
  S : TStringStream;
  XML : TXMLDocument;

begin
  S:= TStringStream.Create(MyXMLString);
  Try
    S.Position:=0;
    XML:=Nil;
    ReadXMLFile(XML,S); // Document XML complet
    // Autre possibilité
    ReadXMLFragment(AParentNode,S); // Lit uniquement un fragment XML. 
  Finally
    S.Free;
  end;
end;

Liens Externes