Sign in Join
Wiki copytemporary

XML Tutorial/pt: what changed

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

Title: XML Tutorial/pt

OldNewLine
1+## Introdução
2+
3+A "Extensible Markup Language" é uma linguagem recomendada pela [W3C](http://www.w3.org/) criada para a troca de informações entre diferentes sistemas. É um formato baseado em texto para armazenar informações. Linguagens modernas de troca de dados, como XHTML, bem como a maioria das tecnologia de WebServices, são baseados no XML.
4+
5+Atualmente há um conjunto de units que fornecem suporte para o XML no Free Pascal. Estas units são chamadas "XMLRead", "XMLWrite" e "DOM" e elas são parte da Biblioteca de Componentes Livre (FCL) do compilador Free Pascal. A FCL já esta presente no caminho de busca (search path) padrão para o compilador no Lazarus, assim você só precisa adicionar as units na claúsula uses para ter suporte ao XML. A FCL não está com sua documentação atualizada (Outubro/2005), assim este pequeno tutorial é uma introdução ao acesso a XML usando estas units.
6+
7+O XML DOM (Modelo Objeto de Documento) é um conjunto objetos padronizados que fornece uma interface similar para uso em diferentes linguagens e sistemas. O padrão só especifica os métodos, propriedades e outras partes da interface do objeto, deixando a implementação liberada para diferentes linguagens. A FCL atualmente tem suporte completo a [XML DOM 1.0](http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/).
8+
9+## Exemplos
10+
11+A seguir tem uma lista de exemplos de manipulação de dados XML com complexidade crescente.
12+
13+### Lendo um nó de texto (text node)
14+
15+Para programadores Delphi: Note que, quando trabalha-se com TXMLDocument, o texto dentro de um Nó é considerado um nó de TEXTO separado. Como resultado, você deve acessar o valor do
16+
17+texto do nó como um nó separado. Como alternativa, a propriedade **TextContent** pode ser usada para extrair o conteúdo de todos os nós de textos abaixo do
18+
19+nó dado, com ambos concatenados.
20+
21+A procedure **ReadXMLFile** sempre cria um novo **TXMLDocument**, assim você não tem que criá-lo com antecedência. Entretanto, tenha certeza de destruir
22+
23+o documento chamando **Free** quando você terminar.
24+
25+Por exemplo, considere o seguinte XML:
26+
27+``` xml
28+ <?xml version="1.0"?>
29+ <request>
30+ <request_type>PUT_FILE</request_type>
31+ <username>123</username>
32+ <password>abc</password>
33+ </request>
34+```
35+
36+O seguinte exemplo de código mostra ambas as formas (correta e incorreta) de pegar o valor do nó de texto:
37+
38+``` pascal
39+ var
40+ PassNode: TDOMNode;
41+ Doc: TXMLDocument;
42+ begin
43+ // Lê no arquivo xml no disco
44+ ReadXMLFile(Doc, 'c:\xmlfiles\test.xml');
45+ // Extrai o nó "password"
46+ PassNode := Doc.DocumentElement.FindNode('password');
47+ // Escreve por extenso o valor do nó selecionado
48+ WriteLn(PassNode.NodeValue); // estará em branco
49+ // O texto do nó é atualmente um "nó filho" separado
50+ WriteLn(PassNode.FirstChild.NodeValue); // mostra corretamente "abc"
51+ // como alternativa
52+ WriteLn(PassNode.TextContent);
53+ // finalmente, libera o documento
54+ Doc.Free;
55+end;
56+```
57+
58+### Mostrando os nomes dos nós
59+
60+Uma nota rápida na navegação pela árvore DOM: Quando você precisar acessar nós em seqüencia, é melhor usar as propriedades **FirstChild** e
61+
62+**NextSibling** (para métodos **GetElementsByTagName**, mas esses serão criados um objeto TDOMNodeList que deverá ser eventualmente liberado. Isso difere
63+
64+das outras implementações DOM como MSXML, porque a implementação feita pela FCL é baseada em objeto, não baseada na interface (interface-based).
65+
66+Os seguintes exemplos demonstram como mostrar os nomes dos nodes para um TMemo localizado em um formulário.
67+
68+A seguir o arquivo XML chamado 'C:\Programas\teste.xml':
69+
70+``` xml
71+ <?xml version="1.0"?>
72+ <images directory="mydir">
73+ <imageNode URL="graphic.jpg" title="">
74+ <Peca DestinoX="0" DestinoY="0">Pecacastelo.jpg1.swf</Peca>
75+ <Peca DestinoX="0" DestinoY="86">Pecacastelo.jpg2.swf</Peca>
76+ </imageNode>
77+ </images>
78+```
79+
80+E aqui o código Pascal para executar a tarefa:
81+
82+``` pascal
83+ var
84+ Documento: TXMLDocument;
85+ Child: TDOMNode;
86+ j: Integer;
87+ begin
88+ ReadXMLFile(Documento, 'C:\Programas\teste.xml');
89+ Memo.Lines.Clear;
90+ // usando as propriedades FirstChild e NextSibling
91+ Child := Documento.DocumentElement.FirstChild;
92+ while Assigned(Child) do
93+ begin
94+ Memo.Lines.Add(Child.NodeName + ' ' + Child.Attributes.Item[0].NodeValue);
95+ // usando método ChildNodes
96+ with Child.ChildNodes do
97+ try
98+ for j := 0 to (Count - 1) do
99+ Memo.Lines.Add(Item[j].NodeName + ' ' + Item[j].FirstChild.NodeValue);
100+ finally
101+ Free;
102+ end;
103+ Child := Child.NextSibling;
104+ end;
105+ Documento.Free;
106+ end;
107+```
108+
109+Isso mostrará:
110+
111+ imageNode graphic.jpg
112+ Peca Pecacastelo.jpg1.swf
113+ Peca Pecacastelo.jpg1.swf
114+
115+### Povoando um TreeView com XML
116+
117+Um uso comum de arquivos XML é analisá-los e mostrar seu conteúdo em uma árvore como formato. Você pode encontrar o componente TTreeView na aba/guia "Common
118+
119+Controls" do Lazarus.
120+
121+A função a seguir pegará um documento XML, previamente carregado de um arquivo ou genrado em código, e povoará um TreeView com seu conteúdo. O *caption* de
122+
123+cada nó consistirá no conteúdo do primeiro atributo de cada nó.
124+
125+``` pascal
126+procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument);
127+var
128+ iNode: TDOMNode;
129+
130+ procedure ProcessNode(Node: TDOMNode; TreeNode: TTreeNode);
131+ var
132+ cNode: TDOMNode;
133+ begin
134+ if Node = nil then Exit; // Pára, se atingir a folha
135+
136+ // Adiciona um nó para a árvore
137+ TreeNode := tree.Items.AddChild(TreeNode, Node.Attributes[0].NodeValue);
138+
139+ // Vai para o primeiro nó filho
140+ cNode := Node.FirstChild;
141+
142+ // Processa todos os nós filhos
143+ while cNode <> nil do
144+ begin
145+ ProcessNode(cNode, TreeNode);
146+ cNode := cNode.NextSibling;
147+ end;
148+ end;
149+
150+begin
151+ iNode := XMLDoc.DocumentElement.FirstChild;
152+ while iNode <> nil do
153+ begin
154+ ProcessNode(iNode, nil); // Recursivo
155+ iNode := iNode.NextSibling;
156+ end;
157+end;
158+```
159+
160+### Modificando um documento XML
161+
162+A primeira coisa a ser lembrada é que TDOMDocumento é o "handle" para o DOM. Você pode pegar uma instância dessa classe criando uma ou carregando um
163+
164+documento XML.
165+
166+Nós, por outro lado, não podem ser criados como um objeto normal. Você *deve* usar os métodos fornecidos por TDOMDocumento para criá-los, e posteriormente
167+
168+usar outros métodos para colocá-los no lugar correto na árvore. Isso ocorre porque os nós devem ser "pertencentes" a um documento específico no DOM.
169+
170+A seguir alguns métodos comuns de TDOMDocument:
171+
172+``` pascal
173+ function CreateElement(const tagName: DOMString): TDOMElement; virtual;
174+ function CreateTextNode(const data: DOMString): TDOMText;
175+ function CreateCDATASection(const data: DOMString): TDOMCDATASection;
176+ virtual;
177+ function CreateAttribute(const name: DOMString): TDOMAttr; virtual;
178+```
179+
180+E aqui um método de exemplo que localizará o item selelcionado em um TTreeView e inseri-rá um nó filho para o documento XML que ele representa. O TreeView
181+
182+deve ser previamente preenchido com o conteúdo de um arquivo XML usando a [[Networking|função XML2Tree]].
183+
184+``` pascal
185+procedure TForm1.actAddChildNode(Sender: TObject);
186+var
187+ Posicao: Integer;
188+ NovoNo: TDomNode;
189+begin
190+ {*******************************************************************
191+ * Detecta o elemento selecionado
192+ *******************************************************************}
193+ if TreeView1.Selected = nil then Exit;
194+
195+ if TreeView1.Selected.Level = 0 then
196+ begin
197+ Posicao := TreeView1.Selected.Index;
198+
199+ NovoNo := XMLDoc.CreateElement('item');
200+ TDOMElement(NovoNo).SetAttribute('nome', 'Item');
201+ TDOMElement(NovoNo).SetAttribute('arquivo', 'Arquivo');
202+ with XMLDoc.DocumentElement.ChildNodes do
203+ begin
204+ Item[Posicao].AppendChild(NovoNo);
205+ Free;
206+ end;
207+
208+ {*******************************************************************
209+ * Atualiza o TreeView
210+ *******************************************************************}
211+ TreeView1.Items.Clear;
212+ XML2Tree(TreeView1, XMLDoc);
213+ end
214+ else if TreeView1.Selected.Level >= 1 then
215+ begin
216+ {*******************************************************************
217+ * Essa função funciona somente no primeiro nível da árvore,
218+ * mas pode facilmente ser modificada para funcionar em quaisquer outros níveis
219+ *******************************************************************}
220+ end;
221+end;
222+```
223+
224+### Criar um TXMLDocument de um string
225+
226+Dado um arquivo XML em MyXmlString, o seguinte código criará esse DOM:
227+
228+``` pascal
229+Var
230+ S : TStringStream;
231+ XML : TXMLDocument;
232+
233+begin
234+ S:= TStringStream.Create(MyXMLString);
235+ Try
236+ S.Position:=0;
237+ XML:=Nil;
238+ ReadXMLFile(XML,S); // Completa o documento XML
239+ // Alternativamente:
240+ ReadXMLFragment(AParentNode,S); // Lê somente um fragmento XML.
241+ Finally
242+ S.Free;
243+ end;
244+end;
245+```
246+
247+### Validando um documento
248+
249+Desde Março de 2007, *DTD validation facility* foi adicionado para o analisador XML da FCL. A validação é a verificação da estrutura lógica do documento
250+
251+conforme as regras pré-definidas, chamadas *Documento Type Definition* (DTD).
252+
253+Aqui está um exemplo de um documento XML com um DTD:
254+
255+``` xml
256+ <?xml version='1.0'?>
257+ <!DOCTYPE root [
258+ <!ELEMENT root (child)+ >
259+ <!ELEMENT child (#PCDATA)>
260+ ]>
261+ <root>
262+ <child>This is a first child.</child>
263+ <child>And this is the second one.</child>
264+ </root>
265+```
266+
267+Esse DTD especifica que o elemento 'root' (raiz) deve ter um ou mais elementos 'child' (filho), e que os elementos 'child' pode ter somente dados de
268+
269+caractere dentro. Se a análise deteca quaisquer violação dessas regras, ela reportará essas violações.
270+
271+Carregar o documento dessa forma é um pouco mais complicado. Assumiremos que temos dados XML em um objeto TStream:
272+
273+``` pascal
274+procedure TMyObject.DOMFromStream(AStream: TStream);
275+var
276+ Parser: TDOMParser;
277+ Src: TXMLInputSource;
278+ TheDoc: TXMLDocument;
279+begin
280+ // cria um objeto analisador
281+ Parser := TDOMParser.Create;
282+ // e a fonte de entrada
283+ Src := TXMLInputSource.Create(AStream);
284+ // nós queremos a validação
285+ Parser.Options.Validate := True;
286+ // associa um manipulador de erro que receberá as notificações
287+ Parser.OnError := @ErrorHandler;
288+ // agora faz o trabalho
289+ Parser.Parse(Src, TheDoc);
290+ // ...e limpeza total
291+ Src.Free;
292+ Parser.Free;
293+end;
294+
295+procedure TMyObject.ErrorHandler(E: EXMLReadError);
296+begin
297+ if E.Severity = esError then // nós estamos interessados somente em erros de validação
298+ writeln(E.Message);
299+end;
300+```
301+
302+### Gerando um arquivo XML
303+
304+Abaixo um código completo para escrever em arquivo XML. Você pode ler o tutorial completo no blog da DeveLazarus (veja [[XML Tutorial/pt|Links Externos]]) Por favor, lembre das bibliotecas DOM e XMLWrite na cláusula uses
305+
306+``` pascal
307+unit Unit1;
308+
309+{$mode objfpc}{$H+}
310+
311+interface
312+
313+uses
314+ Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
315+ DOM, XMLWrite;
316+
317+type
318+ { TForm1 }
319+ TForm1 = class(TForm)
320+ Button1: TButton;
321+ Label1: TLabel;
322+ Label2: TLabel;
323+ procedure Button1Click(Sender: TObject);
324+ private
325+ { private declarations }
326+ public
327+ { public declarations }
328+ end;
329+
330+var
331+ Form1: TForm1;
332+
333+implementation
334+
335+{ TForm1 }
336+
337+procedure TForm1.Button1Click(Sender: TObject);
338+var
339+ xdoc: TXMLDocument; // variável para o documento
340+ noraiz, nopai, nofilho: TDOMNode; // variáveis dos nós
341+begin
342+ //cria um documento
343+ xdoc := TXMLDocument.create;
344+
345+ //cria nó raiz
346+ noraiz := xdoc.CreateElement('cadastro');
347+ Xdoc.Appendchild(noraiz); // salva nó raiz
348+
349+ //cria nó pai
350+ noraiz:= xdoc.DocumentElement;
351+ nopai := xdoc.CreateElement('usuario');
352+ TDOMElement(nopai).SetAttribute('id', '001'); // cria atributo para o nó pai
353+ noraiz.Appendchild(nopai); // salva o nó pai
354+
355+ //cria nó filho
356+ nopai := xdoc.CreateElement('nome'); // cria o nó filho
357+ //TDOMElement(nopai).SetAttribute('sexo', 'M'); // cria atributo
358+ nofilho := xdoc.CreateTextNode('Fernando'); // insere um valor para o nó
359+ nopai.Appendchild(nofilho); // salva nó
360+ noraiz.ChildNodes.Item[0].AppendChild(nopai); // insere o nó filho no nó pai correspondente
361+
362+ //cria nó filho
363+ nopai := xdoc.CreateElement('idade'); // cria nó filho
364+ //TDOMElement(nopai).SetAttribute('ano', '1976'); // cria atributo
365+ nofilho := xdoc.CreateTextNode('32'); // coloca um valor ao nó
366+ nopai.Appendchild(nofilho); // salva o nó
367+ noraiz.ChildNodes.Item[0].AppendChild(nopai); // insere o nó filho no nó pai correspondente
368+
369+ writeXMLFile(xDoc,'teste.xml'); // escreve o XML
370+ Xdoc.free; // libera memória
371+end;
372+
373+initialization
374+ {$I unit1.lrs}
375+
376+end.
377+```
378+
379+Resulta no seguinte arquivo XML:
380+
381+``` xml
382+
383+ <?xml version="1.0" ?>
384+ - <cadastro>
385+ - <usuario id="001">
386+ <nome>Fernando</nome>
387+ <idade>32</idade>
388+ </usuario>
389+ </cadastro>
390+```
391+
392+--Fernandosinesio 22:28, 24 April 2008 (CEST)fernandosinesio@gmail.com
393+
394+## Links Externos
395+
396+- [W3Schools](http://www.w3schools.com/xml/default.asp) Tutorial Xml
397+
398+- [Thomas Zastrow article](http://www.thomas-zastrow.de/texte/fpcxml/index.php) FPC e XML
399+
400+- [Gerando um arquivo XML (Espanhol)](http://develazarus.wordpress.com/2007/07/12/generando-un-archivo-xml/)
401+
402+---
403+*From the Free Pascal wiki, page "XML Tutorial/pt", 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