XML Tutorial/fr
│
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 Extensible Markup Language est un langage recommandé par le W3C créé pour l'echange d'information entre différents systèmes. C'est une façon de stocker l'information sous forme de texte. Les langages modernes d'échange de données comme le XHTML, tout comme la plupart des technologies WebServices, sont basées sur le XML.
Il existe actuellement un ensemble d'unités qui offrent le support du XML au Free Pascal. Ces unités sont appellées "XMLRead", "XMLWrite" et "DOM" et elles font parties de la Free Component Library (FCL) du Free Pascal Compiler. La FCL est déjà dans le chemin de recherche par défaut pour le compilateur de Lazarus, vous n'avez donc besoin que d'ajouter ces unités à votre clause uses afin d'obtenir le support du XML. La FCL n'est pas documentée actuellement (October / 2005), c'est pourquoi ce petit tutoriel vise à introduire l'accès au XML en utilisant ces unités.
Le DOM XML (Document Object Model) est un ensemble d'objets standardisée offrent une interface une interface similaire pour l'utilisation du XML dans 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 1.0.
Examples
Bellow there is a list of XML data manipulation examples with growing complexity.
Reading a text node
For Delphi Programmers: Note that when working with TXMLDocument, the text within a Node is considered a separate TEXT Node. As a result, you must access a node's text value as a separate node. For instance, consider the following XML:
<xml>
<?xml version="1.0" encoding="utf-8"?> <request> <request_type>PUT_FILE</request_type> <username>123</username> <password>abc</password> </request>
</xml>
The following code example shows both the correct and the incorrect ways of getting the value of the text node:
<delphi>
var PassNode: TDOMNode; Doc: TXMLDocument; begin // Read in xml file from disk ReadXMLFile(Doc, 'c:\xmlfiles\test.xml'); // Retrieve the "password" node PassNode := Doc.DocumentElement.FindNode('password'); // Write out value of the selected node WriteLn(PassNode.NodeValue); // will be blank // The text of the node is actually a separate child node WriteLn(PassNode.FirstChild.NodeValue); // correctly prints "abc"
</delphi>
Printing the names of nodes
The following example shows how to print the names of nodes to a TMemo placed on a form.
Bellow is the XML file called 'C:\Programas\teste.xml':
<xml>
<?xml version="1.0" encoding="ISO-8859-1"?> <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>
</xml>
And here the Pascal code to execute the task:
<delphi>
var Documento: TXMLDocument; i, j: Integer; begin ReadXMLFile(Documento, 'C:\Programas\teste.xml'); Memo.Lines.Clear; with Documento.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; Documento.Free; end;
</delphi>
This will print:
imageNode graphic.jpg Peca Pecacastelo.jpg1.swf Peca Pecacastelo.jpg1.swf
Populating a TreeView with XML
One common use of XML files is to parse them and show their contents in a tree like format. You can find the TTreeView component on the "Common Controls" tab on Lazarus.
The function below will take a XML document previously loaded from a file or generated on code, and will populate a TreeView with it´s contents. The caption of each node will be the content of the first attribute of each node.
<delphi> procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument); var
iNode: TDOMNode;
procedure ProcessNode(Node: TDOMNode; TreeNode: TTreeNode); var cNode: TDOMNode; begin if Node = nil then Exit; // Stops if reached a leaf // Adds a node to the tree TreeNode := tree.Items.AddChild(TreeNode, Node.Attributes[0].NodeValue);
// Goes to the child node cNode := Node.ChildNodes.Item[0];
// Processes all child nodes 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); // Recursive iNode := iNode.NextSibling; end;
end; </delphi>
Modifying a XML document
The first thing to remember is that TDOMDocument is the "handle" to the DOM. You can get an instance of this class by creating one or by loading a XML document.
Nodes on the other hand cannot be created like a normal object. You *must* use the methods provided by TDOMDocument to create them, and latter use other methods to put them on the correct place on the tree. This is because nodes must be "owned" by a specific document on DOM.
Below are some common methods from TDOMDocument:
<delphi>
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;
</delphi>
And here an example method that will located the selected item on a TTreeView and then insert a child node to the XML document it represents. The TreeView must be previously filled with the contents of a XML file using the XML2Tree function.
<delphi> procedure TForm1.actAddChildNode(Sender: TObject); var
Posicao: Integer; NovoNo: TDomNode;
begin
{******************************************************************* * Detects the selected element *******************************************************************} 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);
{******************************************************************* * Updates the TreeView *******************************************************************} TreeView1.Items.Clear; XML2Tree(TreeView1, XMLDoc); end else if TreeView1.Selected.Level >= 1 then begin {******************************************************************* * This function only works on the first level of the tree, * but can easely modifyed to work for any number of levels *******************************************************************} end;
end; </delphi>
Create a TXMLDocument from a string
Given al XML file in MyXmlString, the following code will create it's DOM:
<delphi> Var
S : TStringStream; XML : TXMLDocument;
begin
S:= TStringStream.Create(MyXMLString); Try S.Position:=0; XML:=Nil; ReadXMLFile(XML,S); // Complete XML document // Alternatively: ReadXMLFragment(AParentNode,S); // Read only XML fragment. Finally S.Free; end;
end; </delphi>
External Links
- W3Schools Xml Tutorial
- Thomas Zastrow article FPC and XML