Difference between revisions of "XML Tutorial/pt"
(→Introdução: - Update translation) |
|||
Line 9: | Line 9: | ||
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 [http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/|XML DOM 1.0]. | 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 [http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/|XML DOM 1.0]. | ||
− | == | + | == Exemplos == |
− | + | A seguir tem uma lista de exemplos de manipulação de dados XML com complexidade crescente. | |
+ | |||
+ | === Lendo um nó de texto (text node) === | ||
+ | |||
+ | 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 | ||
+ | |||
+ | 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 | ||
+ | |||
+ | nó dado, com ambos concatenados. | ||
+ | |||
+ | A procedure '''ReadXMLFile''' sempre cria um novo '''TXMLDocument''', assim você não tem que criá-lo com antecedência. Entretanto, tenha certeza de destruir | ||
+ | |||
+ | o documento chamando '''Free''' quando você terminar. | ||
+ | |||
+ | Por exemplo, considere o seguinte XML: | ||
+ | |||
+ | <xml> | ||
+ | <?xml version="1.0" encoding="utf-8"?> | ||
+ | <request> | ||
+ | <request_type>PUT_FILE</request_type> | ||
+ | <username>123</username> | ||
+ | <password>abc</password> | ||
+ | </request> | ||
+ | </xml> | ||
+ | |||
+ | O seguinte exemplo de código mostra ambas as formas (correta e incorreta) de pegar o valor do nó de texto: | ||
+ | |||
+ | <delphi> | ||
+ | var | ||
+ | PassNode: TDOMNode; | ||
+ | Doc: TXMLDocument; | ||
+ | begin | ||
+ | // Lê no arquivo xml no disco | ||
+ | ReadXMLFile(Doc, 'c:\xmlfiles\test.xml'); | ||
+ | // Extrai o nó "password" | ||
+ | PassNode := Doc.DocumentElement.FindNode('password'); | ||
+ | // Escreve por extenso o valor do nó selecionado | ||
+ | WriteLn(PassNode.NodeValue); // will be blank | ||
+ | // O texto do nó é atualmente um "nó filho" separado | ||
+ | WriteLn(PassNode.FirstChild.NodeValue); // correctly prints "abc" | ||
+ | // como alternativa | ||
+ | WriteLn(PassNode.TextContent); | ||
+ | // finalmente, libera o documento | ||
+ | Doc.Free; | ||
+ | end; | ||
+ | </delphi> | ||
+ | |||
+ | === Mostrando os nomes dos nós === | ||
+ | |||
+ | 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 | ||
+ | |||
+ | '''NextSibling''' (para métodos '''GetElementsByTagName''', mas esses serão criados um objeto TDOMNodeList que deverá ser eventualmente liberado. Isso difere | ||
+ | |||
+ | das outras implementações DOM como MSXML, porque a implementação feita pela FCL é baseada em objeto, não baseada na interface (interface-based). | ||
+ | |||
+ | Os seguintes exemplos demonstram como mostrar os nomes dos nodes para um TMemo localizado em um formulário. | ||
+ | |||
+ | A seguir o arquivo XML chamado 'C:\Programas\teste.xml': | ||
<xml> | <xml> | ||
− | <?xml version="1.0"?> | + | <?xml version="1.0" encoding="ISO-8859-1"?> |
<images directory="mydir"> | <images directory="mydir"> | ||
<imageNode URL="graphic.jpg" title=""> | <imageNode URL="graphic.jpg" title=""> | ||
Line 23: | Line 81: | ||
</xml> | </xml> | ||
− | + | E aqui o código Pascal para executar a tarefa: | |
<delphi> | <delphi> | ||
var | var | ||
− | + | Documento: TXMLDocument; | |
− | + | Child: TDOMNode; | |
+ | j: Integer; | ||
begin | begin | ||
− | + | ReadXMLFile(Documento, 'C:\Programas\teste.xml'); | |
− | + | Memo.Lines.Clear; | |
− | + | // usando as propriedades FirstChild e NextSibling | |
+ | Child := Documento.DocumentElement.FirstChild; | ||
+ | while Assigned(Child) do | ||
+ | begin | ||
+ | Memo.Lines.Add(Child.NodeName + ' ' + Child.Attributes.Item[0].NodeValue); | ||
+ | // usando método ChildNodes | ||
+ | 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; | ||
+ | </delphi> | ||
+ | |||
+ | Isso mostrará: | ||
+ | |||
+ | <pre> | ||
+ | imageNode graphic.jpg | ||
+ | Peca Pecacastelo.jpg1.swf | ||
+ | Peca Pecacastelo.jpg1.swf | ||
+ | </pre> | ||
+ | |||
+ | === Povoando um TreeView com XML === | ||
+ | |||
+ | 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 | ||
+ | |||
+ | Controls" do Lazarus. | ||
+ | |||
+ | 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 | ||
+ | |||
+ | cada nó consistirá no conteúdo do primeiro atributo de cada nó. | ||
+ | |||
+ | <delphi> | ||
+ | procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument); | ||
+ | var | ||
+ | iNode: TDOMNode; | ||
+ | |||
+ | procedure ProcessNode(Node: TDOMNode; TreeNode: TTreeNode); | ||
+ | var | ||
+ | cNode: TDOMNode; | ||
begin | begin | ||
− | + | if Node = nil then Exit; // Pára, se atingir a folha | |
+ | |||
+ | // Adiciona um nó para a árvore | ||
+ | TreeNode := tree.Items.AddChild(TreeNode, Node.Attributes[0].NodeValue); | ||
+ | |||
+ | // Vai para o primeiro nó filho | ||
+ | cNode := Node.FirstChild; | ||
+ | |||
+ | // Processa todos os nós filhos | ||
+ | while cNode <> nil do | ||
begin | begin | ||
− | + | ProcessNode(cNode, TreeNode); | |
− | + | cNode := cNode.NextSibling; | |
− | |||
− | |||
− | |||
− | |||
end; | end; | ||
end; | end; | ||
− | Documento.Free; | + | |
− | end; | + | begin |
+ | iNode := XMLDoc.DocumentElement.FirstChild; | ||
+ | while iNode <> nil do | ||
+ | begin | ||
+ | ProcessNode(iNode, nil); // Recursivo | ||
+ | iNode := iNode.NextSibling; | ||
+ | end; | ||
+ | end; | ||
+ | </delphi> | ||
+ | |||
+ | === Modificando um documento XML === | ||
+ | |||
+ | 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 | ||
+ | |||
+ | documento XML. | ||
+ | |||
+ | 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 | ||
+ | |||
+ | 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. | ||
+ | |||
+ | A seguir alguns métodos comuns de 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> | ||
+ | |||
+ | 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 | ||
+ | |||
+ | deve ser previamente preenchido com o conteúdo de um arquivo XML usando a [[Networking#Populating a TreeView with XML|função XML2Tree]]. | ||
+ | |||
+ | <delphi> | ||
+ | procedure TForm1.actAddChildNode(Sender: TObject); | ||
+ | var | ||
+ | Posicao: Integer; | ||
+ | NovoNo: TDomNode; | ||
+ | begin | ||
+ | {******************************************************************* | ||
+ | * Detecta o elemento selecionado | ||
+ | *******************************************************************} | ||
+ | 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'); | ||
+ | with XMLDoc.DocumentElement.ChildNodes do | ||
+ | begin | ||
+ | Item[Posicao].AppendChild(NovoNo); | ||
+ | Free; | ||
+ | end; | ||
+ | |||
+ | {******************************************************************* | ||
+ | * Atualiza o TreeView | ||
+ | *******************************************************************} | ||
+ | TreeView1.Items.Clear; | ||
+ | XML2Tree(TreeView1, XMLDoc); | ||
+ | end | ||
+ | else if TreeView1.Selected.Level >= 1 then | ||
+ | begin | ||
+ | {******************************************************************* | ||
+ | * Essa função funciona somente no primeiro nível da árvore, | ||
+ | * mas pode facilmente ser modificada para funcionar em quaisquer outros níveis | ||
+ | *******************************************************************} | ||
+ | end; | ||
+ | end; | ||
+ | </delphi> | ||
+ | |||
+ | === Criar um TXMLDocument de um string === | ||
+ | |||
+ | Dado um arquivo XML em MyXmlString, o seguinte código criará esse DOM: | ||
+ | |||
+ | <delphi> | ||
+ | Var | ||
+ | S : TStringStream; | ||
+ | XML : TXMLDocument; | ||
+ | |||
+ | begin | ||
+ | S:= TStringStream.Create(MyXMLString); | ||
+ | Try | ||
+ | S.Position:=0; | ||
+ | XML:=Nil; | ||
+ | ReadXMLFile(XML,S); // Completa o documento XML | ||
+ | // Alternativamente: | ||
+ | ReadXMLFragment(AParentNode,S); // Lê somente um fragmento XML. | ||
+ | Finally | ||
+ | S.Free; | ||
+ | end; | ||
+ | end; | ||
+ | </delphi> | ||
+ | |||
+ | === Validando um documento === | ||
+ | |||
+ | 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 | ||
+ | |||
+ | conforme as regras pré-definidas, chamadas ''Documento Type Definition'' (DTD). | ||
+ | |||
+ | Aqui está um exemplo de um documento XML com um DTD: | ||
+ | |||
+ | <xml> | ||
+ | <?xml version='1.0' encoding='utf-8'?> | ||
+ | <!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> | ||
+ | </xml> | ||
+ | |||
+ | 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 | ||
+ | |||
+ | caractere dentro. Se a análise deteca quaisquer violação dessas regras, ela reportará essas violações. | ||
+ | |||
+ | Carregar o documento dessa forma é um pouco mais complicado. Assumiremos que temos dados XML em um objeto TStream: | ||
+ | |||
+ | <delphi> | ||
+ | procedure TMyObject.DOMFromStream(AStream: TStream); | ||
+ | var | ||
+ | Parser: TDOMParser; | ||
+ | Src: TXMLInputSource; | ||
+ | TheDoc: TXMLDocument; | ||
+ | begin | ||
+ | // cria um objeto analisador | ||
+ | Parser := TDOMParser.Create; | ||
+ | // e a fonte de entrada | ||
+ | Src := TXMLInputSource.Create(AStream); | ||
+ | // nós queremos a validação | ||
+ | Parser.Options.Validate := True; | ||
+ | // associa um manipulador de erro que receberá as notificações | ||
+ | Parser.OnError := @ErrorHandler; | ||
+ | // agora faz o trabalho | ||
+ | Parser.Parse(Src, TheDoc); | ||
+ | // ...e limpeza total | ||
+ | Src.Free; | ||
+ | Parser.Free; | ||
+ | end; | ||
+ | |||
+ | procedure TMyObject.ErrorHandler(E: EXMLReadError); | ||
+ | begin | ||
+ | if E.Severity = esError then // nós estamos interessados somente em erros de validação | ||
+ | writeln(E.Message); | ||
+ | end; | ||
</delphi> | </delphi> | ||
+ | |||
+ | == Miscelania == | ||
+ | |||
+ | '''ToDo: Arrumar isso e traduzir para o inglês!''' | ||
+ | |||
+ | ---- | ||
Código inteiro para escrever em arquivo XML: | Código inteiro para escrever em arquivo XML: |
Revision as of 21:44, 26 April 2008
│
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) │
Introdução
A "Extensible Markup Language" é uma linguagem recomendada pela W3C 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.
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.
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 DOM 1.0.
Exemplos
A seguir tem uma lista de exemplos de manipulação de dados XML com complexidade crescente.
Lendo um nó de texto (text node)
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
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
nó dado, com ambos concatenados.
A procedure ReadXMLFile sempre cria um novo TXMLDocument, assim você não tem que criá-lo com antecedência. Entretanto, tenha certeza de destruir
o documento chamando Free quando você terminar.
Por exemplo, considere o seguinte XML:
<xml>
<?xml version="1.0" encoding="utf-8"?> <request> <request_type>PUT_FILE</request_type> <username>123</username> <password>abc</password> </request>
</xml>
O seguinte exemplo de código mostra ambas as formas (correta e incorreta) de pegar o valor do nó de texto:
<delphi>
var PassNode: TDOMNode; Doc: TXMLDocument; begin // Lê no arquivo xml no disco ReadXMLFile(Doc, 'c:\xmlfiles\test.xml'); // Extrai o nó "password" PassNode := Doc.DocumentElement.FindNode('password'); // Escreve por extenso o valor do nó selecionado WriteLn(PassNode.NodeValue); // will be blank // O texto do nó é atualmente um "nó filho" separado WriteLn(PassNode.FirstChild.NodeValue); // correctly prints "abc" // como alternativa WriteLn(PassNode.TextContent); // finalmente, libera o documento Doc.Free;
end; </delphi>
Mostrando os nomes dos nós
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
NextSibling (para métodos GetElementsByTagName, mas esses serão criados um objeto TDOMNodeList que deverá ser eventualmente liberado. Isso difere
das outras implementações DOM como MSXML, porque a implementação feita pela FCL é baseada em objeto, não baseada na interface (interface-based).
Os seguintes exemplos demonstram como mostrar os nomes dos nodes para um TMemo localizado em um formulário.
A seguir o arquivo XML chamado '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>
E aqui o código Pascal para executar a tarefa:
<delphi>
var Documento: TXMLDocument; Child: TDOMNode; j: Integer; begin ReadXMLFile(Documento, 'C:\Programas\teste.xml'); Memo.Lines.Clear; // usando as propriedades FirstChild e NextSibling Child := Documento.DocumentElement.FirstChild; while Assigned(Child) do begin Memo.Lines.Add(Child.NodeName + ' ' + Child.Attributes.Item[0].NodeValue); // usando método ChildNodes 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;
</delphi>
Isso mostrará:
imageNode graphic.jpg Peca Pecacastelo.jpg1.swf Peca Pecacastelo.jpg1.swf
Povoando um TreeView com XML
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
Controls" do Lazarus.
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
cada nó consistirá no conteúdo do primeiro atributo de cada nó.
<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; // Pára, se atingir a folha // Adiciona um nó para a árvore TreeNode := tree.Items.AddChild(TreeNode, Node.Attributes[0].NodeValue);
// Vai para o primeiro nó filho cNode := Node.FirstChild;
// Processa todos os nós filhos 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); // Recursivo iNode := iNode.NextSibling; end;
end; </delphi>
Modificando um documento XML
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
documento XML.
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
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.
A seguir alguns métodos comuns de 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>
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
deve ser previamente preenchido com o conteúdo de um arquivo XML usando a função XML2Tree.
<delphi> procedure TForm1.actAddChildNode(Sender: TObject); var
Posicao: Integer; NovoNo: TDomNode;
begin
{******************************************************************* * Detecta o elemento selecionado *******************************************************************} 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'); with XMLDoc.DocumentElement.ChildNodes do begin Item[Posicao].AppendChild(NovoNo); Free; end;
{******************************************************************* * Atualiza o TreeView *******************************************************************} TreeView1.Items.Clear; XML2Tree(TreeView1, XMLDoc); end else if TreeView1.Selected.Level >= 1 then begin {******************************************************************* * Essa função funciona somente no primeiro nível da árvore, * mas pode facilmente ser modificada para funcionar em quaisquer outros níveis *******************************************************************} end;
end; </delphi>
Criar um TXMLDocument de um string
Dado um arquivo XML em MyXmlString, o seguinte código criará esse DOM:
<delphi> Var
S : TStringStream; XML : TXMLDocument;
begin
S:= TStringStream.Create(MyXMLString); Try S.Position:=0; XML:=Nil; ReadXMLFile(XML,S); // Completa o documento XML // Alternativamente: ReadXMLFragment(AParentNode,S); // Lê somente um fragmento XML. Finally S.Free; end;
end; </delphi>
Validando um documento
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
conforme as regras pré-definidas, chamadas Documento Type Definition (DTD).
Aqui está um exemplo de um documento XML com um DTD:
<xml>
<?xml version='1.0' encoding='utf-8'?> <!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>
</xml>
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
caractere dentro. Se a análise deteca quaisquer violação dessas regras, ela reportará essas violações.
Carregar o documento dessa forma é um pouco mais complicado. Assumiremos que temos dados XML em um objeto TStream:
<delphi> procedure TMyObject.DOMFromStream(AStream: TStream); var
Parser: TDOMParser; Src: TXMLInputSource; TheDoc: TXMLDocument;
begin
// cria um objeto analisador Parser := TDOMParser.Create; // e a fonte de entrada Src := TXMLInputSource.Create(AStream); // nós queremos a validação Parser.Options.Validate := True; // associa um manipulador de erro que receberá as notificações Parser.OnError := @ErrorHandler; // agora faz o trabalho Parser.Parse(Src, TheDoc); // ...e limpeza total Src.Free; Parser.Free;
end;
procedure TMyObject.ErrorHandler(E: EXMLReadError); begin
if E.Severity = esError then // nós estamos interessados somente em erros de validação writeln(E.Message);
end; </delphi>
Miscelania
ToDo: Arrumar isso e traduzir para o inglês!
Código inteiro para escrever em arquivo XML: (Lembrar das bibliotecas DOM e XMLWrite na cláusula uses)
<delphi>
unit Unit1; {$mode objfpc}{$H+} interface
uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, DOM, XMLWrite, StdCtrls;
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; //variável para o documento noraiz, nopai, nofilho: TDOMNode; //variáveis dos Nós
begin
//cria um documento xdoc := TXMLDocument.create;
//cria Nó raiz noraiz := xdoc.CreateElement('cadastro'); Xdoc.Appendchild(noraiz); //salva Nó raiz
//cria Nó pai noraiz:= xdoc.DocumentElement; nopai := xdoc.CreateElement('usuario'); TDOMElement(nopai).SetAttribute('id', '001'); //cria atributo para o Nó pai noraiz.Appendchild(nopai); //salva nó pai
//cria Nó Filho nopai := xdoc.CreateElement('nome'); //cria Nó Filho //TDOMElement(nopai).SetAttribute('sexo', 'M'); //cria atributo nofilho := xdoc.CreateTextNode('Fernando'); //insere valor para o nó nopai.Appendchild(nofilho); //salva nó noraiz.ChildNodes.Item[0].AppendChild(nopai); //insere o nó filho ao nó pai correspondente
//cria Nó Filho nopai := xdoc.CreateElement('idade'); //cria Nó Filho //TDOMElement(nopai).SetAttribute('ano', '1976'); //cria atributo nofilho := xdoc.CreateTextNode('32'); //insere coloca valor nó nopai.Appendchild(nofilho); //salva nó noraiz.ChildNodes.Item[0].AppendChild(nopai); //insere o nó filho ao nó pai correspondente
writeXMLFile(xDoc,'teste.xml'); //escreve XML Xdoc.free; //libera memória end; initialization {$I unit1.lrs} end.
</delphi>
Resulta em:
<xml>
<?xml version="1.0" ?> - <cadastro> - <usuario id="001"> <nome>Fernando</nome> <idade>32</idade> </usuario> </cadastro>
</xml>
baseado no site: http://develazarus.wordpress.com/2007/07/12/generando-un-archivo-xml/
--Fernandosinesio 22:28, 24 April 2008 (CEST)fernandosinesio@gmail.com