Difference between revisions of "XML Tutorial/it"

From Lazarus wiki
Jump to navigationJump to search
(New page: {{XML Tutorial}} == Introduzione == L'Extensible Markup Language un linguaggio raccomandato dal [http://www.w3.org/ W3C] creato per l'interscambio di informazioni tra sistemi differenti....)
 
m (Fixed syntax highlighting)
 
(14 intermediate revisions by 5 users not shown)
Line 3: Line 3:
 
== Introduzione ==
 
== Introduzione ==
  
L'Extensible Markup Language un linguaggio raccomandato dal [http://www.w3.org/ W3C] creato per l'interscambio di informazioni tra sistemi differenti. Si tratta di un sistema di memorizzazione di informazioni basato su file di testo. Linguaggi moderni di interscambio di dati come XHTML, così come la maggior parte delle tecnologie WebService, sono basati su XML.
+
L'Extensible Markup Language è un linguaggio raccomandato dal [http://www.w3.org/ W3C] creato per l'interscambio di informazioni tra sistemi differenti. Si tratta di un sistema di memorizzazione di informazioni basato su file di testo. Linguaggi moderni di interscambio di dati come XHTML, così come la maggior parte delle tecnologie WebService, sono basati su XML.
  
 
Al momento esistono una serie di unit che forniscono supporto per XML su Free Pascal. Queste unit sono chiamate "XMLRead", "XMLWrite" e "DOM" e sono parte della Free Component Library (FCL) del Free Pascal Compiler. La FCL si trova già nei percorsi di ricerca di default per il compilatore in Lazarus, così bisogna soltanto aggiungere queste unit alla clausola uses per avere il supporto di XML. La FCL al momento (Ottobre / 2005) non è documentata, quindi questo breve tutorial introdurrà XML tramite l'utilizzo di queste unit.
 
Al momento esistono una serie di unit che forniscono supporto per XML su Free Pascal. Queste unit sono chiamate "XMLRead", "XMLWrite" e "DOM" e sono parte della Free Component Library (FCL) del Free Pascal Compiler. La FCL si trova già nei percorsi di ricerca di default per il compilatore in Lazarus, così bisogna soltanto aggiungere queste unit alla clausola uses per avere il supporto di XML. La FCL al momento (Ottobre / 2005) non è documentata, quindi questo breve tutorial introdurrà XML tramite l'utilizzo di queste unit.
Line 11: Line 11:
 
== Esempi ==
 
== Esempi ==
  
Di seguito c'è una lista di esempi di manipolazione dati tramite XML di complessità crescente.
+
Di seguito c'è una lista di esempi di manipolazione dati tramite XML di complessità crescente. Le unit necessarie per compilare le funzioni di esempio (e in generale per lavorare con l'XML) sono: DOM, XMLRead, XMLWrite, XMLCfg, XMLUtils, XMLStreaming. Nella maggior parte degli esempi sono necessarie solo alcune di queste, comunque.
  
 
=== Leggere un nodo di testo ===
 
=== Leggere un nodo di testo ===
  
For Delphi Programmers:
+
Per Programmatori Delphi:
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. Alternatively, the '''TextContent''' property may be used to retrieve content of all text nodes beneath the given one, concatenated together.
+
Notare che quando si lavora con TXMLDocument, il testo all'interno di un Node viene considerato come un TEXT Node separatoQuindi si deve accedere al valore del testo del nodo come se si trattasse di un nodo separato. In alternativa, è possibile utilizzare la proprietà '''TextContent''' per ottenere il contenuto di tutti i nodi di testo al di sotto del nodo specificato, concatenati assieme.
  
The '''ReadXMLFile''' procedure always creates a new '''TXMLDocument''', so you don't have to create it beforehand. However, be sure to destroy the document by calling '''Free''' when you are done.
+
La procedure '''ReadXMLFile''' crea sempre un nuovo '''TXMLDocument''', quindi non c'è bisogno di crearlo prima. In ogni caso, assicuratevi di distruggere il documento tramite una chiamata a '''Free''' quando avete terminato.
  
For instance, consider the following XML:
+
Per esempio, consideriamo il seguente XML:
  
<xml>
+
<syntaxhighlight lang="xml">
 
  <?xml version="1.0"?>
 
  <?xml version="1.0"?>
 
  <request>
 
  <request>
Line 29: Line 29:
 
   <password>abc</password>
 
   <password>abc</password>
 
  </request>
 
  </request>
</xml>
+
</syntaxhighlight>
  
The following code example shows both the correct and the incorrect ways of getting the value of the text node:
+
Il seguente codice di esempio mostra sia il modo corretto che quello non corretto di ottenere il valore del testo del nodo:
  
<delphi>
+
<syntaxhighlight lang=pascal>
 
  var
 
  var
 
   PassNode: TDOMNode;
 
   PassNode: TDOMNode;
Line 51: Line 51:
 
   Doc.Free;
 
   Doc.Free;
 
end;
 
end;
</delphi>
+
</syntaxhighlight>
  
 
=== Stampare i nomi dei nodi ===
 
=== Stampare i nomi dei nodi ===
  
A quick note on navigating the DOM tree: When you need to access nodes in sequence, it is best to use '''FirstChild''' and '''NextSibling''' properties (to iterate forward), or '''LastChild''' and '''PreviousSibling''' (to iterate backward). For random access it is possible to use '''ChildNodes''' or '''GetElementsByTagName''' methods, but these will create a TDOMNodeList object which eventually must be freed. This differs from other DOM implementations like MSXML, because FCL implementation is object-based, not interface-based.
+
Una nota veloce sulla navigazione di un albero DOM: quando c'è bisogno di accedere i nodi in sequenza, è preferibile utilizzare le proprietà '''FirstChild''' e '''NextSibling''' (per scorrerlo in avanti), o '''LastChild''' e '''PreviousSibling''' (per scorrerlo indietro). Per un accesso random è possibile utilizzare i metodi '''ChildNodes''' o '''GetElementsByTagName''', ma questi creeranno un oggetto TDOMNodeList che alla fine deve essere rilasciato. Questo comportamento differisce da altre implementazioni di DOM come MSXML, perché l'implementazione di FCL è basata sugli oggetti, non sulle interfacce.
  
The following example shows how to print the names of nodes to a TMemo placed on a form.
+
Il seguente esempio mostra come stampare i nomi dei nodi in un TMemo posizionato su un form.
  
Bellow is the XML file called 'C:\Programas\teste.xml':
+
Qui sotto c'è il file XML chiamato 'C:\Programas\teste.xml':
  
<xml>
+
<syntaxhighlight lang="xml">
 
  <?xml version="1.0"?>
 
  <?xml version="1.0"?>
 
  <images directory="mydir">
 
  <images directory="mydir">
Line 69: Line 69:
 
   </imageNode>
 
   </imageNode>
 
  </images>
 
  </images>
</xml>
+
</syntaxhighlight>
  
And here the Pascal code to execute the task:
+
E qui il codice Pascal per eseguire il compito:
  
<delphi>
+
<syntaxhighlight lang=pascal>
 
  var
 
  var
 
   Documento: TXMLDocument;
 
   Documento: TXMLDocument;
Line 98: Line 98:
 
   Documento.Free;
 
   Documento.Free;
 
  end;
 
  end;
</delphi>
+
</syntaxhighlight>
  
This will print:
+
Questo stamperà:
  
 
<pre>
 
<pre>
Line 110: Line 110:
 
=== Popolare un TreeView tramite XML ===
 
=== Popolare un TreeView tramite 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.
+
Un utilizzo comune dei files XML è quello di eseguire un parsing su di essi e mostrare il loro contenuto in una struttura ad albero. E' possibile trovare il componente TTreeView nella linguetta "Common Controls" in 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.
+
La funzione qui in basso prenderà un documento XML precedentemente caricato da file o generato via codice e popolerà un TreeView con il suo contenuto. La caption di ogni nodo sarà il contenuto del primo attributo di ogni nodo.
  
<delphi>
+
<syntaxhighlight lang=pascal>
 
procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument);
 
procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument);
 
var
 
var
Line 122: Line 122:
 
   var
 
   var
 
     cNode: TDOMNode;
 
     cNode: TDOMNode;
 +
    s: string;
 
   begin
 
   begin
 
     if Node = nil then Exit; // Stops if reached a leaf
 
     if Node = nil then Exit; // Stops if reached a leaf
 
      
 
      
 
     // Adds a node to the tree
 
     // Adds a node to the tree
     TreeNode := tree.Items.AddChild(TreeNode, Node.Attributes[0].NodeValue);
+
    if Node.HasAttributes and (Node.Attributes.Length>0) then
 +
      s:=Node.Attributes[0].NodeValue
 +
    else
 +
      s:='';
 +
     TreeNode := tree.Items.AddChild(TreeNode, s);
  
 
     // Goes to the child node
 
     // Goes to the child node
Line 147: Line 152:
 
   end;
 
   end;
 
end;
 
end;
</delphi>
+
</syntaxhighlight>
  
 
=== Modificare un documento XML ===
 
=== Modificare un documento XML ===
  
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.
+
La prima cosa da ricordare è che TDOMDocument rappresenta l'"handle" al DOM. E' possibile ottenere una istanza di questa classe creandone una o caricando un documento XML.
  
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.
+
D'altro canto i nodi non possono essere creati come normali oggetti. Per crearli si *devono* utilizzare i metodi forniti da TDOMDocument, quindi utilizzare altri metodi per posizionarli nella posizione corretta nell'albero. Questo accade perché in DOM i nodi devono "appartenere" ad un documento specifico.
  
Below are some common methods from TDOMDocument:
+
Qui di seguito sono riportati alcuni metodi comuni di TDOMDocument:
  
<delphi>
+
<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 163: Line 168:
 
     virtual;
 
     virtual;
 
   function CreateAttribute(const name: DOMString): TDOMAttr; virtual;
 
   function CreateAttribute(const name: DOMString): TDOMAttr; virtual;
</delphi>
+
</syntaxhighlight>
  
And here an example method that will locate 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 [[Networking#Populating a TreeView with XML|XML2Tree function]].
+
E qui un metodo di esempio che localizza l'elemento selezionato in un TTreeView e inserisce un nodo figlio nel documento XML che rappresenta. Il TreeView deve essere preventivamente riempito con il contenuto di un file XML utilizzando la [[Networking#Populating a TreeView with XML|funzione XML2Tree]].
  
<delphi>
+
<syntaxhighlight lang=pascal>
 
procedure TForm1.actAddChildNode(Sender: TObject);
 
procedure TForm1.actAddChildNode(Sender: TObject);
 
var
 
var
Line 205: Line 210:
 
   end;
 
   end;
 
end;
 
end;
</delphi>
+
</syntaxhighlight>
  
 
=== Creare un TXMLDocument da una stringa ===
 
=== Creare un TXMLDocument da una stringa ===
  
Given al XML file in MyXmlString, the following code will create it's DOM:
+
Dato un file XML in MyXmlString, il seguente codice creerà il corrispondente DOM:
  
<delphi>
+
<syntaxhighlight lang=pascal>
 
Var
 
Var
 
   S : TStringStream;
 
   S : TStringStream;
Line 228: Line 233:
 
   end;
 
   end;
 
end;
 
end;
</delphi>
+
</syntaxhighlight>
  
 
=== Validare un documento ===
 
=== Validare un documento ===
  
Since March 2007, DTD validation facility has been added to the FCL XML parser. Validation is checking that logical structure of the document conforms to the predefined rules, called ''Document Type Definition'' (DTD).
+
A partire da Marzo 2007, al parser XML della FCL è stata aggiunta la capacità di validare i DTD. La validazione consiste nel controllare che la struttura logica del documento sia conforme a regole prestabilite, chiamate ''Document Type Definition'' (DTD).
  
Here is an example of XML document with a DTD:
+
Ecco un esempio di un documento XML con un DTD:
  
<xml>
+
<syntaxhighlight lang="xml">
 
   <?xml version='1.0'?>
 
   <?xml version='1.0'?>
 
   <!DOCTYPE root [
 
   <!DOCTYPE root [
Line 246: Line 251:
 
     <child>And this is the second one.</child>
 
     <child>And this is the second one.</child>
 
   </root>
 
   </root>
</xml>
+
</syntaxhighlight>
  
This DTD specifies that 'root' element must have one or more 'child' elements, and that 'child' elements may have only character data inside. If parser detects any violations from these rules, it will report them.
+
Questo DTD specifica che l'elemento 'root' deve avere uno o più elementi 'child', e che gli elementi 'child' possono avere al loro interno soltanto caratteri. Se il parser individua una violazione di queste regole, le riporterà.
  
Loading such document is slightly more complicated. Let's assume we have XML data in a TStream object:
+
Caricare un documento di questo tipo è leggermente più complicato. Assumiamo di avere dei dati XML in un oggetto TStream:
  
<delphi>
+
<syntaxhighlight lang=pascal>
 
procedure TMyObject.DOMFromStream(AStream: TStream);
 
procedure TMyObject.DOMFromStream(AStream: TStream);
 
var
 
var
Line 279: Line 284:
 
     writeln(E.Message);
 
     writeln(E.Message);
 
end;
 
end;
</delphi>
+
</syntaxhighlight>
  
 
=== Generare un file XML ===
 
=== Generare un file XML ===
  
Below is the complete code to write in a XML file.
+
Di seguito c'è il codice completo per scrivere  su un file XML.
(This was taken from a tutorial in DeveLazarus blog )
+
(E' stato preso da un tutorial sul blog DeveLazarus)
Please, remember DOM and XMLWrite libs in uses clause
+
Ricordate di aggiungere le librerie DOM e XMLWrite sotto la clausola uses
  
<delphi>
+
<syntaxhighlight lang=pascal>
 
unit Unit1;
 
unit Unit1;
  
Line 348: Line 353:
 
   nofilho := xdoc.CreateTextNode('32');              // insert a value to node
 
   nofilho := xdoc.CreateTextNode('32');              // insert a value to node
 
   parentNode.Appendchild(nofilho);                        // save node
 
   parentNode.Appendchild(nofilho);                        // save node
   .ChildNodes.Item[0].AppendChild(parentNode);       // insert a childnode in respective parent node
+
   RootNode.ChildNodes.Item[0].AppendChild(parentNode); // insert a childnode in respective parent node
  
 
   writeXMLFile(xDoc,'teste.xml');                    // write to XML
 
   writeXMLFile(xDoc,'teste.xml');                    // write to XML
Line 358: Line 363:
  
 
end.
 
end.
</delphi>
+
</syntaxhighlight>
  
The  result will be the XML file below:
+
Il risultato sarà il file XML seguente:
<xml>
+
<syntaxhighlight lang="xml">
 
<?xml version="1.0"?>
 
<?xml version="1.0"?>
 
<register>
 
<register>
Line 369: Line 374:
 
   </usuario>
 
   </usuario>
 
</register>
 
</register>
</xml>
+
</syntaxhighlight>
  
 
--[[User:Fernandosinesio|Fernandosinesio]] 22:28, 24 April 2008 (CEST)fernandosinesio@gmail.com
 
--[[User:Fernandosinesio|Fernandosinesio]] 22:28, 24 April 2008 (CEST)fernandosinesio@gmail.com
Line 375: Line 380:
 
=== Codifica ===
 
=== Codifica ===
  
Starting from SVN revision 12582, XML reader is able to process data in any encoding by using external decoders. See [[XML_Decoders]] for more details.
+
A partire dalla revisione SVN 12582, il lettore XML è capace di processare i dati in qualsiasi codifica attraverso l'uso di decodificatori esterni. Vedere [[XML_Decoders]] per maggiori dettagli.
  
According to the XML standard, the encoding attribute in the first line of the XML is optional in case the actual encoding is UTF-8 or UTF-16 (which is detected by presence of the BOM). As of version 0.9.26 of Lazarus, there is an encoding property in a TXMLDocument, but it is ignored. writeXMLFile always uses UTF-8 and doesn´t generate an encoding attribute in first line of the XML file.
+
Secondo lo standard XML, l'attributo encoding nella prima linea del file XML è opzionale nel caso in cui l'effettiva codifica sia UTF-8 o UTF-16 (che viene individuata dalla presenza di BOM). Dalla versione 0.9.26 di Lazarus, c'è una proprietà encoding in TXMLDocument, ma è ignorata. writeXMLFile utilizza in ogni caso UTF-8 e non genera un attributo encoding nella prima linea del file XML.
  
 
== Link Esterni ==
 
== Link Esterni ==
Line 383: Line 388:
 
* [http://www.w3schools.com/xml/default.asp W3Schools] Xml Tutorial
 
* [http://www.w3schools.com/xml/default.asp W3Schools] Xml Tutorial
  
* <s>[http://www.thomas-zastrow.de/texte/fpcxml/index.php Thomas Zastrow article] FPC and XML</s>
+
* <s>[http://www.thomas-zastrow.de/texte/fpcxml/index.php Thomas Zastrow article]</s> [http://web.archive.org/web/20080802150722/http://www.thomas-zastrow.de/texte/fpcxml/index.php link alternativo] FPC and XML
 
 
[[Category:Free Component Library]]
 
  
 
----
 
----
[[Multithreaded Application Tutorial]]
 
 
{{AutoCategory}}
 

Latest revision as of 02:45, 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)

Introduzione

L'Extensible Markup Language è un linguaggio raccomandato dal W3C creato per l'interscambio di informazioni tra sistemi differenti. Si tratta di un sistema di memorizzazione di informazioni basato su file di testo. Linguaggi moderni di interscambio di dati come XHTML, così come la maggior parte delle tecnologie WebService, sono basati su XML.

Al momento esistono una serie di unit che forniscono supporto per XML su Free Pascal. Queste unit sono chiamate "XMLRead", "XMLWrite" e "DOM" e sono parte della Free Component Library (FCL) del Free Pascal Compiler. La FCL si trova già nei percorsi di ricerca di default per il compilatore in Lazarus, così bisogna soltanto aggiungere queste unit alla clausola uses per avere il supporto di XML. La FCL al momento (Ottobre / 2005) non è documentata, quindi questo breve tutorial introdurrà XML tramite l'utilizzo di queste unit.

XML DOM (Document Object Model) sono una serie di oggetti standardizzati che forniscono un'interfaccia simile per l'utilizzo di XML con differenti linguaggi e su differenti sistemi. Lo standard specifica soltanto i metodi, le proprietà e altre parti dell'interfaccia dell'oggetto, lasciando l'implementazione libera per i diversi linguaggi. La FCL al momento offre pieno supporto per XML DOM 1.0.

Esempi

Di seguito c'è una lista di esempi di manipolazione dati tramite XML di complessità crescente. Le unit necessarie per compilare le funzioni di esempio (e in generale per lavorare con l'XML) sono: DOM, XMLRead, XMLWrite, XMLCfg, XMLUtils, XMLStreaming. Nella maggior parte degli esempi sono necessarie solo alcune di queste, comunque.

Leggere un nodo di testo

Per Programmatori Delphi: Notare che quando si lavora con TXMLDocument, il testo all'interno di un Node viene considerato come un TEXT Node separato. Quindi si deve accedere al valore del testo del nodo come se si trattasse di un nodo separato. In alternativa, è possibile utilizzare la proprietà TextContent per ottenere il contenuto di tutti i nodi di testo al di sotto del nodo specificato, concatenati assieme.

La procedure ReadXMLFile crea sempre un nuovo TXMLDocument, quindi non c'è bisogno di crearlo prima. In ogni caso, assicuratevi di distruggere il documento tramite una chiamata a Free quando avete terminato.

Per esempio, consideriamo il seguente XML:

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

Il seguente codice di esempio mostra sia il modo corretto che quello non corretto di ottenere il valore del testo del nodo:

 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"
  // alternatively
  WriteLn(PassNode.TextContent);
  // finally, free the document
  Doc.Free;
end;

Stampare i nomi dei nodi

Una nota veloce sulla navigazione di un albero DOM: quando c'è bisogno di accedere i nodi in sequenza, è preferibile utilizzare le proprietà FirstChild e NextSibling (per scorrerlo in avanti), o LastChild e PreviousSibling (per scorrerlo indietro). Per un accesso random è possibile utilizzare i metodi ChildNodes o GetElementsByTagName, ma questi creeranno un oggetto TDOMNodeList che alla fine deve essere rilasciato. Questo comportamento differisce da altre implementazioni di DOM come MSXML, perché l'implementazione di FCL è basata sugli oggetti, non sulle interfacce.

Il seguente esempio mostra come stampare i nomi dei nodi in un TMemo posizionato su un form.

Qui sotto c'è il file XML chiamato 'C:\Programas\teste.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>

E qui il codice Pascal per eseguire il compito:

 var
   Documento: TXMLDocument;
   Child: TDOMNode;
   j: Integer;
 begin
   ReadXMLFile(Documento, 'C:\Programas\teste.xml');
   Memo.Lines.Clear;
   // using FirstChild and NextSibling properties
   Child := Documento.DocumentElement.FirstChild;
   while Assigned(Child) do
   begin
     Memo.Lines.Add(Child.NodeName + ' ' + Child.Attributes.Item[0].NodeValue);
     // using ChildNodes method
     with Child.ChildNodes do
     try
       for j := 0 to (Count - 1) do
         Memo.Lines.Add(Item[j].NodeName + ' ' + Item[j].FirstChild.NodeValue);
     finally
       Free;
     end;
     Child := Child.NextSibling;
   end;
   Documento.Free;
 end;

Questo stamperà:

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

Popolare un TreeView tramite XML

Un utilizzo comune dei files XML è quello di eseguire un parsing su di essi e mostrare il loro contenuto in una struttura ad albero. E' possibile trovare il componente TTreeView nella linguetta "Common Controls" in Lazarus.

La funzione qui in basso prenderà un documento XML precedentemente caricato da file o generato via codice e popolerà un TreeView con il suo contenuto. La caption di ogni nodo sarà il contenuto del primo attributo di ogni nodo.

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; // Stops if reached a leaf
    
    // Adds a node to the tree
    if Node.HasAttributes and (Node.Attributes.Length>0) then
      s:=Node.Attributes[0].NodeValue
    else
      s:=''; 
    TreeNode := tree.Items.AddChild(TreeNode, s);

    // Goes to the child node
    cNode := Node.FirstChild;

    // Processes all child nodes
    while cNode <> nil do
    begin
      ProcessNode(cNode, TreeNode);
      cNode := cNode.NextSibling;
    end;
  end;
    
begin
  iNode := XMLDoc.DocumentElement.FirstChild;
  while iNode <> nil do
  begin
    ProcessNode(iNode, nil); // Recursive
    iNode := iNode.NextSibling;
  end;
end;

Modificare un documento XML

La prima cosa da ricordare è che TDOMDocument rappresenta l'"handle" al DOM. E' possibile ottenere una istanza di questa classe creandone una o caricando un documento XML.

D'altro canto i nodi non possono essere creati come normali oggetti. Per crearli si *devono* utilizzare i metodi forniti da TDOMDocument, quindi utilizzare altri metodi per posizionarli nella posizione corretta nell'albero. Questo accade perché in DOM i nodi devono "appartenere" ad un documento specifico.

Qui di seguito sono riportati alcuni metodi comuni di 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;

E qui un metodo di esempio che localizza l'elemento selezionato in un TTreeView e inserisce un nodo figlio nel documento XML che rappresenta. Il TreeView deve essere preventivamente riempito con il contenuto di un file XML utilizzando la funzione XML2Tree.

procedure TForm1.actAddChildNode(Sender: TObject);
var
  position: Integer;
  NovoNo: TDomNode;
begin
  {*******************************************************************
  *  Detects the selected element
  *******************************************************************}
  if TreeView1.Selected = nil then Exit;

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

    NovoNo := XMLDoc.CreateElement('item');
    TDOMElement(NovoNo).SetAttribute('nome', 'Item');
    TDOMElement(NovoNo).SetAttribute('arquivo', 'Arquivo');
    with XMLDoc.DocumentElement.ChildNodes do
    begin
      Item[position].AppendChild(NovoNo);
      Free;
    end;

    {*******************************************************************
    *  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;

Creare un TXMLDocument da una stringa

Dato un file XML in MyXmlString, il seguente codice creerà il corrispondente DOM:

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;

Validare un documento

A partire da Marzo 2007, al parser XML della FCL è stata aggiunta la capacità di validare i DTD. La validazione consiste nel controllare che la struttura logica del documento sia conforme a regole prestabilite, chiamate Document Type Definition (DTD).

Ecco un esempio di un documento XML con un DTD:

  <?xml version='1.0'?>
  <!DOCTYPE root [
  <!ELEMENT root (child)+ >
  <!ELEMENT child (#PCDATA)>
  ]>
  <root>
    <child>This is a first child.</child>
    <child>And this is the second one.</child>
  </root>

Questo DTD specifica che l'elemento 'root' deve avere uno o più elementi 'child', e che gli elementi 'child' possono avere al loro interno soltanto caratteri. Se il parser individua una violazione di queste regole, le riporterà.

Caricare un documento di questo tipo è leggermente più complicato. Assumiamo di avere dei dati XML in un oggetto TStream:

procedure TMyObject.DOMFromStream(AStream: TStream);
var
  Parser: TDOMParser;
  Src: TXMLInputSource;
  TheDoc: TXMLDocument;
begin
  // create a parser object
  Parser := TDOMParser.Create;
  // and the input source
  Src := TXMLInputSource.Create(AStream);
  // we want validation
  Parser.Options.Validate := True;
  // assign a error handler which will receive notifications
  Parser.OnError := @ErrorHandler;
  // now do the job
  Parser.Parse(Src, TheDoc);
  // ...and cleanup
  Src.Free;
  Parser.Free;
end;

procedure TMyObject.ErrorHandler(E: EXMLReadError);
begin
  if E.Severity = esError then  // we are interested in validation errors only
    writeln(E.Message);
end;

Generare un file XML

Di seguito c'è il codice completo per scrivere su un file XML. (E' stato preso da un tutorial sul blog DeveLazarus) Ricordate di aggiungere le librerie DOM e XMLWrite sotto la clausola uses

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
  DOM, XMLWrite;

type
  { TForm1 }
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
  
var
  Form1: TForm1;
  
implementation

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  xdoc: TXMLDocument;                                  // variable to document
  RootNode, parentNode, nofilho: TDOMNode;                    // variable to nodes
begin
  //create a document
  xdoc := TXMLDocument.create;

  //create a root node
  RootNode := xdoc.CreateElement('register');
  Xdoc.Appendchild(RootNode);                           // save root node

  //create a parent node
  RootNode:= xdoc.DocumentElement;
  parentNode := xdoc.CreateElement('usuario');
  TDOMElement(parentNode).SetAttribute('id', '001');       // create atributes to parent node
  RootNode.Appendchild(parentNode);                          // save parent node

  //create a child node
  parentNode := xdoc.CreateElement('nome');                // create a child node
  //TDOMElement(parentNode).SetAttribute('sexo', 'M');     // create atributes
  nofilho := xdoc.CreateTextNode('Fernando');         // insert a value to node
  parentNode.Appendchild(nofilho);                         // save node
  RootNode.ChildNodes.Item[0].AppendChild(parentNode);       // insert child node in respective parent node

  //create a child node
  parentNode := xdoc.CreateElement('idade');               // create a child node
  //TDOMElement(parentNode).SetAttribute('ano', '1976');   // create atributes
  nofilho := xdoc.CreateTextNode('32');               // insert a value to node
  parentNode.Appendchild(nofilho);                         // save node
  RootNode.ChildNodes.Item[0].AppendChild(parentNode); // insert a childnode in respective parent node

  writeXMLFile(xDoc,'teste.xml');                     // write to XML
  Xdoc.free;                                          // free memory
end;

initialization
  {$I unit1.lrs}

end.

Il risultato sarà il file XML seguente:

<?xml version="1.0"?>
<register>
  <usuario id="001">
    <nome>Fernando</nome>
    <idade>32</idade>
  </usuario>
</register>

--Fernandosinesio 22:28, 24 April 2008 (CEST)fernandosinesio@gmail.com

Codifica

A partire dalla revisione SVN 12582, il lettore XML è capace di processare i dati in qualsiasi codifica attraverso l'uso di decodificatori esterni. Vedere XML_Decoders per maggiori dettagli.

Secondo lo standard XML, l'attributo encoding nella prima linea del file XML è opzionale nel caso in cui l'effettiva codifica sia UTF-8 o UTF-16 (che viene individuata dalla presenza di BOM). Dalla versione 0.9.26 di Lazarus, c'è una proprietà encoding in TXMLDocument, ma è ignorata. writeXMLFile utilizza in ogni caso UTF-8 e non genera un attributo encoding nella prima linea del file XML.

Link Esterni